题目:
第一次做的代码:超出时间限制
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
//思路:利用双指针
//指针i 指向数组的首位, 指针 j 指向数组的末尾
//指针i的目的是找到偶数,指针j的目的是找到奇数
int i=0, j=nums.size()-1;
// i从前往后找,j从后往前找
//当i>=j时,便完成 数组前面是奇数, 后面是奇数
while(i!=j){
// 如果i找到的是偶数,且j找到的是奇数,交换它们的值
if(nums[i]%2==0 && nums[i]%2 !=0){
swap(nums[i],nums[j]);
}
// i要找的是偶数,找不到i往后移动,最终要实现i的左边全是奇数
if(nums[i]%2!=0){
++i;
}
//如果j找到的是偶数,j往前移动,最终要实现j的右边边全是奇数
if(nums[j]%2==0){
--j;
}
}
return nums;
}
};
反思:思路不对,考虑不周
正确的思路应该是:
- 指针 i 要找数组中的偶数,直到找到为止;同样,指针 j 要找数组中的奇数,直到找到为止
- 第一步的目的是一定让 i 找到偶数, j 找到奇数, 方便后序的交换
- 交换找到的两个数
此外,在第一步的时候,有个特殊情况我未考虑到,举个栗子:数组里元素是 1,2,4,6,8
i 找到偶数,指向数字2; j 找到奇数,指向数字1;如果不加限制条件,那么这两个数交换之后 就显得很不合理。
😔可见我的代码漏洞百出 。。。稀碎(ง •_•)ง)
所以呢,应该在第一步 i 和 j 找数的时候,加上限制条件满足 i < j 则执行,等 i 找到了偶数, j 找到了奇数,那么就可以交换了
看过题解之后,在判断所找的数是奇数还是偶数时,可以用位运算(为什么呢?位运算比较快——我的理解)
奇数 和 1 按位与 == 1;偶数 和 1 按位与 ==0
因此,最终的代码:
class Solution {
public:
vector<int> exchange(vector<int>& nums) {
//思路:利用双指针
//指针i 指向数组的首位, 指针 j 指向数组的末尾
//指针i的目的是找到偶数,指针j的目的是找到奇数
int i=0, j=nums.size()-1;
// i从前往后找,j从后往前找
//当i>=j时,便完成 数组前面是奇数, 后面是奇数
while(i<j){
//奇数 和 1 按位与得 1, 偶数 和 1 按位与得 0
// i 直到 找到偶数为止, ==的优先级要高于&, 要加()
while(i<j && (nums[i]&1)==1){
i++;
}
// j 直到 找到奇数为止
while(i<j && (nums[j]&1)==0){
j--;
}
//好了, i找到了偶数, j找到了奇数,那么达成协议,交易成功【手动滑稽】
swap(nums[i], nums[j]);
}
return nums;
}
};
过几天我还要再做一遍,今天是看了题解,再过几天能不能自己写出来就不一定了U•ェ•*U
继续刷ing (。・∀・)ノ