英文原文
Given an integer array nums
, move all the even integers at the beginning of the array followed by all the odd integers.
Return any array that satisfies this condition.
Example 1:
Input: nums = [3,1,2,4] Output: [2,4,3,1] Explanation: The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted.
Example 2:
Input: nums = [0] Output: [0]
Constraints:
1 <= nums.length <= 5000
0 <= nums[i] <= 5000
中文题目
给定一个非负整数数组 A
,返回一个数组,在该数组中, A
的所有偶数元素之后跟着所有奇数元素。
你可以返回满足此条件的任何数组作为答案。
示例:
输入:[3,1,2,4] 输出:[2,4,3,1] 输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
提示:
1 <= A.length <= 5000
0 <= A[i] <= 5000
通过代码
官方题解
方法 1:排序
想法和算法
使用排序算法,按照模 2 的结果排序。
class Solution {
public int[] sortArrayByParity(int[] A) {
Integer[] B = new Integer[A.length];
for (int t = 0; t < A.length; ++t)
B[t] = A[t];
Arrays.sort(B, (a, b) -> Integer.compare(a%2, b%2));
for (int t = 0; t < A.length; ++t)
A[t] = B[t];
return A;
/* Alternative:
return Arrays.stream(A)
.boxed()
.sorted((a, b) -> Integer.compare(a%2, b%2))
.mapToInt(i -> i)
.toArray();
*/
}
}
class Solution(object):
def sortArrayByParity(self, A):
A.sort(key = lambda x: x % 2)
return A
复杂度分析
- 时间复杂度:$O(N\log N)$,其中 $N$ 是
A
的长度。 - 空间复杂度:排序空间为 $O(N)$,取决于内置的
sort
函数实现。
方法 2:两边扫描
想法和算法
第一遍输出偶数,第二遍输出奇数。
class Solution {
public int[] sortArrayByParity(int[] A) {
int[] ans = new int[A.length];
int t = 0;
for (int i = 0; i < A.length; ++i)
if (A[i] % 2 == 0)
ans[t++] = A[i];
for (int i = 0; i < A.length; ++i)
if (A[i] % 2 == 1)
ans[t++] = A[i];
return ans;
}
}
class Solution(object):
def sortArrayByParity(self, A):
return ([x for x in A if x % 2 == 0] +
[x for x in A if x % 2 == 1])
复杂度分析
- 时间复杂度:$O(N)$,其中 $N$ 是
A
的长度。 - 空间复杂度:$O(N)$,存储结果的数组。
方法 3:原地算法
想法
如果希望原地排序,可以使用快排,一个经典的算法。
算法
维护两个指针 i
和 j
,循环保证每刻小于 i
的变量都是偶数(也就是 A[k] % 2 == 0
当 k < i
),所有大于 j
的都是奇数。
所以, 4 种情况针对 (A[i] % 2, A[j] % 2)
:
- 如果是
(0, 1)
,那么万事大吉i++
并且j--
。 - 如果是
(1, 0)
,那么交换两个元素,然后继续。 - 如果是
(0, 0)
,那么说明i
位置是正确的,只能i++
。 - 如果是
(1, 1)
,那么说明j
位置是正确的,只能j--
。
通过这 4 种情况,循环不变量得以维护,并且 j-i
不断变小。最终就可以得到奇偶有序的数组。
class Solution {
public int[] sortArrayByParity(int[] A) {
int i = 0, j = A.length - 1;
while (i < j) {
if (A[i] % 2 > A[j] % 2) {
int tmp = A[i];
A[i] = A[j];
A[j] = tmp;
}
if (A[i] % 2 == 0) i++;
if (A[j] % 2 == 1) j--;
}
return A;
}
}
class Solution(object):
def sortArrayByParity(self, A):
i, j = 0, len(A) - 1
while i < j:
if A[i] % 2 > A[j] % 2:
A[i], A[j] = A[j], A[i]
if A[i] % 2 == 0: i += 1
if A[j] % 2 == 1: j -= 1
return A
复杂度分析
- 时间复杂度:$O(N)$,其中 $N$ 是
A
的长度。循环的每一步都让j-i
至少减少了一。(注意虽然快排的复杂度是 $O(N\log N)$,但是我们只需要一轮扫描就可以了)。 - 空间复杂度:$O(1)$,不需要额外空间。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
60104 | 85819 | 70.0% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|