kylin来刷题啦-Day09:922. 按奇偶排序数组 II

135 阅读1分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

922. 按奇偶排序数组 II

题目描述

给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。

对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。

你可以返回任何满足上述条件的数组作为答案。

示例 :

输入:[4,2,5,7]

输出:[4,5,2,7]

解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。

提示:

  1. 2 <= A.length <= 20000
  2. A.length % 2 == 0
  3. 0 <= A[i] <= 1000

友情链接

leetcode-cn.com/problems/so…

思路解析

因为将数组里面的数分成了两类嘛,一类奇数,一类偶数。且要实现一个数组里面再分别将这两种数合并按照位置的奇偶性重新取数,很自然的想到了用两个栈分别存储这两种数。再开一个新的长度一样的数组,在顺序访问数组的过程中,位置是奇数的就从奇数栈中取一个数,位置是偶数的就从偶数栈里面取一个数。

这种方法虽然最容易想到,但是效率不是很高。空间复杂度要 2n ,时间复杂度也要 2n 。

算法实现

class Solution {
    public int[] sortArrayByParityII(int[] nums) {
        LinkedList<Integer> stackJ=new LinkedList<>();
        LinkedList<Integer> stackO=new LinkedList<>();
        for(int item:nums){
            if (0 == item % 2) {
                stackO.push(item);
            } else {
                stackJ.push(item);
            }
        }

        int[] result=new int[nums.length];
        for(int i=0;i<nums.length;++i){
             if (i%2==0){
                result[i]=stackO.pop();
            }else {
                result[i]=stackJ.pop();
            }
        }
        return result;
    }
}

运行结果

image.png

进阶设计

步骤:

  1. 按顺序找到第一个位置为奇数但是值不是奇数的元素;
  2. 按顺序找到第一个位置为偶数但是值不是偶数的元素;
  3. 交换这两个位置的元素;
  4. 重复上述步骤。
class Solution {
    public int[] sortArrayByParityII(int[] nums) {
        int even=0,odd=1;
        while(true){
            while(even<nums.length&&nums[even]%2==0){
                even+=2;
            }
            while(odd<nums.length&&nums[odd]%2!=0){
                odd+=2;
            }
            if(even>=nums.length||odd>=nums.length){
                return nums;
            }
            int temp=nums[even];
            nums[even]=nums[odd];
            nums[odd]=temp;
        }
    }
}

image.png

时间复杂度 O(n); 空间复杂度 O(n); 妙!