原题链接:https://leetcode-cn.com/problems/sort-array-by-parity/
此题的目的就是将数组中的元素从左到右按照偶数在前,奇数在后进行排布
对于类似的一前一后的问题,我们可以使用头尾指针来解决
大致思想如何呢,看图说明:
start为头指针开始指向第一个元素,即 start=0
end为尾指针开始指向最后一个元素,即 end=A.length-1
那么此时 start 和 end 所对应的数字有如下四种情况:
- start 指向一个偶数,end 指向一个奇数
- start 指向一个偶数,end 指向一个偶数
- start 指向一个奇数,end 指向一个偶数
- start 指向一个奇数,end 指向一个奇数
第1种情况,start 已经指向偶数,end 也已经指向奇数,其实此时已经保证了偶数在前,奇数在后的情况,所以两者所指向的值都不需要移动,则继续考虑下一对数据即可,即 start++ end--
第2种情况,start 指向一个偶数,end 也指向一个偶数,此时 start 的偶数已经保证在前,无非是 end 的偶数需要向前移动,移动到哪里呢?应该是 start 之后出现的第1个奇数,所以让 start 继续后移找奇数即可 即 start++
第3中情况,start 指向一个奇数,end 指向一个偶数,此时只需将两者交换位置即可,保证偶在前奇在后,交换后参照第1中情况
第4中情况,start 指向一个奇数,end 也指向一个奇数,同第2种情况,end 的奇数已经在后,此时只需要 start 的奇数后移即可,移动到哪里呢,就得需要 end 向前寻找第1个偶数,即 start++
综上,只需要在 start 和 end 移动的过程中,按照上述四种情况操作,最终数组排序完毕
合适排序完毕呢,相信大家已经发现,当 start >= end 时 排序即完毕
举例:比如给定数组[1,2,3,5,8,4,9,6,7]
1 2 3 5 8 4 9 6 7
l r
此时左奇右奇,前者需后移,则r--
1 2 3 5 8 4 9 6 7
l r
此时左奇右偶,交换l和r所指元素的位置
6 2 3 5 8 4 9 1 7
l r
此时左偶右奇,l++,r--
6 2 3 5 8 4 9 1 7
l r
此时左偶右奇,l++,r--
6 2 3 5 8 4 9 1 7
l r
此时左奇右偶,交换l和r所指元素的位置
6 2 4 5 8 3 9 1 7
l r
此时左偶右奇,l++,r--
6 2 4 5 8 3 9 1 7
l r
此时左奇右偶,交换l和r所指元素的位置
6 2 4 8 5 3 9 1 7
l r
此时左偶右奇,l++,r--
6 2 4 8 5 3 9 1 7
r l
此时 l>=r 结束
代码如下:
class Solution {
public int[] sortArrayByParity(int[] A) {
int left=0;
int right=A.length-1;
while(left<right){
if(A[left]%2==1&&A[right]%2==0){
int temp=A[left];
A[left]=A[right];
A[right]=temp;
}else if(A[left]%2==0&&A[right]%2==1){
left++;
right--;
}else if(A[left]%2==0&&A[right]%2==0){
left++;
}else{
right--;
}
}
return A;
}
}
额外的
题目中并没有要求严格的数字顺序
如果加一个要求,就是交换后不能改变原先偶数之间的相对顺序和奇数之间的相对顺序的话,如何去做呢?
意味着数组[1,2,3,4,5,6]的排序结果只能是唯一的[2,4,6,1,3,5],偶数和奇数之间的相对顺序没有改变
那么我们可以借助插入排序的思想来做,为什么,因为插入排序是一个稳定的排序,此处关于排序的稳定性请自行百度看看什么意思,不多说了,直接放代码看吧,自己按照代码的流程走一遍
class Solution {
public int[] sortArrayByParity(int[] A) {
int e=0;
for(int i=1;i<A.length;i++){
e=A[i];
if(e%2==0){
int j;
for(j=i;j>0&&A[j-1]%2==1;j--){
A[j]=A[j-1];
}
A[j]=e;
}
}
return A;
}
}