持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情
题目
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。
解题思路
题目要求把奇数放在数组前半部分,偶数放在数组后半部分,需要遍历数组中元素将奇数全部移动到前面即可(无需考虑元素数字排序问题)。
双指针解法
定义两个指针:i,j两个分别用于寻找偶数和奇数值。
- 第一个指针初始化指向数组第一个数值,第二个指针初始化指向数组最后一个数值。
- 第一个指针向前移动,第二个指针向后移动,当第一个指针找到偶数时停下同理第二个指针找到奇数数时停下。
- 当双指针都满足要求找到满足条件后值做交换。
- 直到双指针重合为止(替换完毕)。
public int[] exchange(int[] nums) {
int i = 0;
int j = nums.length - 1;
while(i < j){
int left = nums[i];
int right = nums[j];
if(left % 2 == 0 && right % 2 != 0){
nums[j] = left;
nums[i] = right;
i++;
j--;
}
if(left % 2 != 0) i++; // 奇数右移
if(right % 2 == 0) j--; // 偶数左移
}
return nums;
}
双指针解法可以想到之前做的另外一道题目:旋转数组的最小值 同样是运用双指针首尾往内合并(二分法)找到最小值,解法使用方法存在相似性。
双指针进阶解法
既然是双指针找到对应满足条件的值,那么就可以先循环一遍的值再循环另外一边(只要在限定条件内即可)。同理当本题目修改条件后同样也能满足要求,比如把奇数偶数判断条件修改为是否可被3整除,又或者是否为负数等条件只需要将如下代码中 while(nums[i] % 2 != 0 && i < j)和while(nums[j] % 2 == 0 && i < j)条件替换一下即可。
public int[] exchange(int[] nums) {
int i = 0;
int j = nums.length - 1;
while(i < j){
while(nums[i] % 2 != 0 && i < j) i++; // 条件封装
while(nums[j] % 2 == 0 && i < j) j--; // 条件封装
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
i++;
j--;
}
return nums;
}