一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情。
周五了,五一假期来了
按奇偶排序数组
该题出自力扣的905题 - 按奇偶排序数组【简单题】
审题
给你一个整数数组
nums,将nums中的的所有偶数元素移动到数组的前面,后跟所有奇数元素。
返回满足此条件的 任一数组 作为答案。
-
题型很简单,就是给出一个整型数组,需要把数组划分为两组,前半部分是偶数,后半部分是奇数,并且没有排序的要求
-
首当其冲的便是想到双指针的对撞指针做法,在不断后移的过程中对调
-
解法:对撞指针
- 首先判断数组的长度是否等于1,如果等于1则直接返回,无论奇偶无意义了
- 定义左指针和右指针,循环对撞指针
- 首先判断两个指针当前的数值是否奇偶数,并且相对移动两个指针,直到当前互为奇偶数,则原地对调位置
- 最后输出数组即可
-
时间复杂度为O(n),虽然在for循环内有两个while循环,但是并不影响每个元素只被循环一次
-
空间复杂度为O(1),因为是在原地处理数据的
除此以外还有一种优化方案,就是数组内对调的实现 -
一开始使用的是new 一个初始值作为中转,去调换两个数值
-
可以使用异或,也就是利用 一个数异或两次另一个数 等于自己本身,去实现调换参数
-
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
-
nums[l] ^= nums[r]; nums[r] ^= nums[l]; nums[l++]^=nums[r--];
-
编码
class Solution {
public int[] sortArrayByParity(int[] nums) {
if (nums.length == 1)return nums;
int l = 0,r = nums.length-1;
while (l<r){
if ((nums[l] &1) == 1 && (nums[r] &1) != 1){
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
while ( l<r &&(nums[l] &1) == 0){
l++;
}
while ( l<r && (nums[r] &1) == 1) {
r--;
}
}
return nums;
}
}