给定一个非负整数数组 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-array-by-parity
方法 1:排序算法
public static int[] sortArrayByParity(int[] A) {
Integer[] B = new Integer[A.length];
for (int i = 0; i < A.length; i++)
B[i] = A[i];
/*
//匿名内部类
Arrays.sort(B, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 % 2 - o2 % 2;
}
});
//lambda表达式标准形式
Arrays.sort(B, (a, b) -> {
return a % 2 - b % 2;
});
*/
//lambda表达式简化形式
Arrays.sort(B, (a, b) -> a % 2 - b % 2);
for (int t = 0; t < A.length; ++t)
A[t] = B[t];
return A;
}
方法 2:两边扫描
public static int[] sortArrayByParity2(int[] A) {
int[] ans = new int[A.length];
int t = 0, p = A.length - 1;
for (int i = 0; i < A.length; i++) {
if (A[i] % 2 == 0) {
ans[t++] = A[i];
} else {
ans[p--] = A[i];
}
}
return ans;
}
方法 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 不断变小。最终就可以得到奇偶有序的数组。
public static int[] sortArrayByParity3(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;
}