一、题目描述
Given an array A of non-negative integers, return an array consisting of all the even elements of A,
followed by all the odd elements of A.
You may return any answer array that satisfies this condition.
Input: [3,1,2,4]
Output: [2,4,3,1]
The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted.
二、题解
解题思路有三:
- 双
list
分别存储奇偶数 - 双端队列存储
- 双指针(基于交换排序)
方法一:双 list 存储
数组 中所有的偶数单独存储在 中,所有的奇数单独存储在 中,最终,先遍历 ,后遍历 。
public int[] sortArrayByParity(int[] A) {
ArrayList<Integer> evenList = new ArrayList<>();
ArrayList<Integer> oddList = new ArrayList<>();
for (int i = 0; i < A.length; i++) {
if((A[i] & 1) == 0) evenList.add(A[i]);
else oddList.add(A[i]);
}
int i = 0;
for(int even : evenList) { // 偶数放前面
A[i++] = even;
}
for(int odd : oddList) { // 奇数放后面
A[i++] = odd;
}
return A;
}
基于以上的先将偶数存储到 ,后将奇数存储到 的思想,我们可以用一个数组 加上一个临时指针 改善一下代码:
public int[] sortArrayByParity(int[] A) {
int[] arr = new int[A.length];
int j = 0; // 临时指针
for (int i = 0; i < A.length; i++) {
if ((A[i] & 1) == 0) // 偶数放前面
arr[j++] = A[i];
}
for (int i = 0; i < A.length; i++) {
if ((A[i] & 1) == 1) // 奇数放后面
arr[j++] = A[i];
}
return arr;
}
复杂度分析
- 时间复杂度:, 为 数组 的元素个数。
- 空间复杂度:,前一种方法使用了两个 存储数据,但 的总个数为;后一种方法使用一个大小为 新的数组存储数据
方法二:双端队列
将第一个数放到 中,剩余的数需判断奇偶,奇数就加到到队列的最后面,如果是偶数就加到队列的最前面。
- 第一个数无需考虑是奇还是偶,因为它的位置不是固定不变的。
public int[] sortArrayByParity(int[] A) {
LinkedList<Integer> list = new LinkedList<>();
list.addLast(A[0]);
for (int i = 1; i < A.length; i++) {
if((A[i] & 1) == 0) list.addFirst(A[i]); // 偶数放最前面
else list.addLast(A[i]); // 奇数放最后面
}
int i = 0;
for(int n : list) {
A[i++] = n;
}
return A;
}
复杂度分析
- 时间复杂度:, 为 数组 的元素个数。
- 空间复杂度:,方法使用了一个 存储数据。
方法三:双指针
前两种方法都是从左往右遍历,逐个检查元素的奇偶性,其实可以基于交换排序的思想,从如何交换?交换的前提得是两个元素才能进行,那么从两端往中间遍历数组就必不可少了。
- 普通的排序比较的是元素的大小。
- 这里却比较的是奇偶性,
题目要求是的结果数列是偶奇序,且不管大小进行排列,可以让位于开头且为偶数的要与位于结尾且的奇数的进行交换。
public int[] sortArrayByParity(int[] A) {
int Even = 0;
int Odd = A.length - 1;
while (Even < Odd) {
if( (A[Even] & 1) == 1 && (A[Odd] & 1) == 0 ) {
swap(A, Even, Odd); // 如果Even指向奇数,Odd指向偶数,那么交换
}
else if( (A[Even] & 1) == 0)// 如果Even指向偶数,Even继续向右探索
Even++;
else if( (A[Odd] & 1) == 1) // 如果Odd指向奇数,Odd继续向左探索
Odd--;
}
return A;
}
private static void swap(int[] A, int i, int j) {
int t = A[i];
A[i] = A[j];
A[j] = t;
}
复杂度分析
- 时间复杂度:, 为 数组 的元素个数。
- 空间复杂度:,无额外存储空间的使用。
来源:CSDN
作者:PANjj99
链接:https://blog.csdn.net/qq_43539599/article/details/104207520