先上题目
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
题目链接:剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
看到题目就很容易想到用双指针,进行前后交换,本以为能够轻松AC。但是出现了一个之前从未注意的一个BUG,直接上代码。
class Solution {
public int[] exchange(int[] nums) {
int i = 0;
int j = nums.length - 1;
while (i < j) {
while ((nums[i] & 1) == 1 && i < j)
i++;
while ((nums[j] & 1) == 0 && i < j)
j--;
nums[i] = nums[i] ^ nums[j];
nums[j] = nums[i] ^ nums[j];
nums[i] = nums[i] ^ nums[j];
i++;
j--;
}
return nums;
}
}
错误样例
分析:
由于数组样例内的元素值都为奇数,变量i肯定直接循环加到nums.length-1。此时i的值与j的值相等,所以nums[i]和nums[j]表示的是相同的数组元素。可以视作为同一个变量。同一变量使用异或^的方法交换值便会变为0
使用常规的三值交换,便可避免这一问题。
class Solution {
public int[] exchange(int[] nums) {
int i = 0;
int j = nums.length - 1;
while (i < j) {
while ((nums[i] & 1) == 1 && i < j)
i++;
while ((nums[j] & 1) == 0 && i < j)
j--;
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
i++;
j--;
}
return nums;
注:值相同的两个变量,使用异或^的方法交换值是没有问题。不可混淆。
int i = 1;
int j = 1;
i = i ^ j;
j = i ^ j;
i = i ^ j;
System.out.println(i + " " + j);// 1 1