文章目录
题目
标题和出处
标题:按奇偶排序数组
出处:905. 按奇偶排序数组
难度
2 级
题目描述
要求
给定一个整数数组 nums \texttt{nums} nums,将 nums \texttt{nums} nums 中的所有偶数元素移动到数组的前面,所有奇数元素移动到数组的后面。
返回满足此条件的任意数组。
示例
示例 1:
输入: nums = [3,1,2,4] \texttt{nums = [3,1,2,4]} nums = [3,1,2,4]
输出: [2,4,3,1] \texttt{[2,4,3,1]} [2,4,3,1]
解释: [4,2,3,1] \texttt{[4,2,3,1]} [4,2,3,1]、 [2,4,1,3] \texttt{[2,4,1,3]} [2,4,1,3] 和 [4,2,1,3] \texttt{[4,2,1,3]} [4,2,1,3] 也是正确答案。
示例 2:
输入: nums = [0] \texttt{nums = [0]} nums = [0]
输出: [0] \texttt{[0]} [0]
数据范围
- 1 ≤ nums.length ≤ 5000 \texttt{1} \le \texttt{nums.length} \le \texttt{5000} 1≤nums.length≤5000
 - 0 ≤ nums[i] ≤ 5000 \texttt{0} \le \texttt{nums[i]} \le \texttt{5000} 0≤nums[i]≤5000
 
解法一
思路和算法
最直观的做法是新建一个结果数组,将原数组中的元素依次填入结果数组,结果数组满足所有偶数元素在前面,所有奇数元素在后面。为了确保结果数组中的所有偶数在所有奇数前面,需要分别从数组的起始位置和结束位置开始填入偶数和奇数。
用 sorted \textit{sorted} sorted 表示结果数组,用 left \textit{left} left 和 right \textit{right} right 分别表示数组 sorted \textit{sorted} sorted 中填入偶数和奇数的下标,初始时 left \textit{left} left 和 right \textit{right} right 分别指向数组的起始位置和结束位置。
对于原数组中的每个元素 num \textit{num} num,如果 num \textit{num} num 是偶数则填入 sorted [ left ] \textit{sorted}[\textit{left}] sorted[left],如果 num \textit{num} num 是奇数则填入 sorted [ right ] \textit{sorted}[\textit{right}] sorted[right],然后将相应的下标向数组中间的位置移动一位(将 left \textit{left} left 向右移动一位,或将 right \textit{right} right 向左移动一位)。
遍历原数组结束之后,原数组中的所有元素都填入结果数组。由于整个过程中都有 left ≤ right \textit{left} \le \textit{right} left≤right,因此结果数组中的所有偶数在所有奇数前面。
代码
            
            
              java
              
              
            
          
          class Solution {
    public int[] sortArrayByParity(int[] nums) {
        int length = nums.length;
        int[] sorted = new int[length];
        int left = 0, right = length - 1;
        for (int num : nums) {
            if (num % 2 == 0) {
                sorted[left] = num;
                left++;
            } else {
                sorted[right] = num;
                right--;
            }
        }
        return sorted;
    }
}
        复杂度分析
- 
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要遍历数组 nums \textit{nums} nums 一次将每个元素填入结果数组。
 - 
空间复杂度: O ( 1 ) O(1) O(1)。注意返回值不计入空间复杂度。
 
解法二
思路和算法
解法一需要新建一个结果数组,也可以在原数组上修改。
用 left \textit{left} left 和 right \textit{right} right 分别表示数组 nums \textit{nums} nums 中填入偶数和奇数的下标,初始时 left \textit{left} left 和 right \textit{right} right 分别指向数组的起始位置和结束位置。
当 left < right \textit{left} < \textit{right} left<right 时,如果 nums [ left ] \textit{nums}[\textit{left}] nums[left] 是偶数则将 left \textit{left} left 向右移动直到 nums [ left ] \textit{nums}[\textit{left}] nums[left] 是奇数,如果 nums [ right ] \textit{nums}[\textit{right}] nums[right] 是奇数则将 right \textit{right} right 向左移动直到 nums [ right ] \textit{nums}[\textit{right}] nums[right] 是偶数,移动两个下标的过程中如果遇到 left = right \textit{left} = \textit{right} left=right 则停止移动下标。当停止移动下标时,可能的两种情况是 left < right \textit{left} < \textit{right} left<right 或 left = right \textit{left} = \textit{right} left=right。
- 
如果 left < right \textit{left} < \textit{right} left<right,则 nums [ left ] \textit{nums}[\textit{left}] nums[left] 是奇数, nums [ right ] \textit{nums}[\textit{right}] nums[right] 是偶数,因此一个奇数在一个偶数的前面,将 nums [ left ] \textit{nums}[\textit{left}] nums[left] 和 nums [ right ] \textit{nums}[\textit{right}] nums[right] 交换,然后将 left \textit{left} left 向右移动一位,将 right \textit{right} right 向左移动一位,并重复上述操作。
 - 
如果 left = right \textit{left} = \textit{right} left=right,则当前下标的左边的元素都是偶数,当前下标的右边的元素都是奇数,无论当前下标的元素是偶数还是奇数,整个数组都已经符合所有偶数在所有奇数前面的条件,因此返回数组 nums \textit{nums} nums。
 
由于 left \textit{left} left 和 right \textit{right} right 相向移动,因此两个下标一定会相遇,此时的数组 nums \textit{nums} nums 即为符合所有偶数在所有奇数前面的数组。
代码
            
            
              java
              
              
            
          
          class Solution {
    public int[] sortArrayByParity(int[] nums) {
        int left = 0, right = nums.length - 1;
        while (left < right) {
            while (left < right && nums[left] % 2 == 0) {
                left++;
            }
            while (left < right && nums[right] % 2 != 0) {
                right--;
            }
            if (left < right) {
                int temp = nums[left];
                nums[left] = nums[right];
                nums[right] = temp;
                left++;
                right--;
            }
        }
        return nums;
    }
}
        复杂度分析
- 
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要遍历数组 nums \textit{nums} nums 中的每个元素一次,每次交换操作的时间是 O ( 1 ) O(1) O(1)。
 - 
空间复杂度: O ( 1 ) O(1) O(1)。注意返回值不计入空间复杂度。