数组元素按照奇偶性左右排列,记录一个错误!!!(力扣 num 21)
看评论区的大哥大姐提供的思路是:
1. 定义两个数组下标,记为i和j,分别指向数组的头和尾;
2. 首先从左往右寻找第一个偶数,找到后,从右往左寻找第一个奇数;
3. 交换,直到i>=j为止
思路很清晰,实现也就几句代码的事情
#include <iostream>
#include <vector>
using namespace std;
vector<int> exchange(vector<int> &nums)
{
//双指针
//分别定义i j 指向数组的首尾两端,题目要求数组左边是奇数,右边是偶数
//所以,可以首先从左边找到第一个偶数,然后从右边找到第一个奇数,交换;直到最后,i==j结束遍历
//可以保证,i的左边都是奇数,j的右边都是偶数;
int i = 0, j = nums.size() - 1;
while (i <j)
{
while (nums[i] % 2 == 1)
i++;
while (nums[j] % 2 == 0)
j--;
std::swap(nums[i],nums[j]);
}
return nums;
}
int main()
{
vector<int> nums = {
1, 2, 3, 4};
nums=exchange(nums);
return 0;
}
于是就出现了考虑不周到的问题:
我输入:1,2,3,4 ;
输出:1,2,3,4 ;
定睛一看,才发现了问题的本质:
第一轮:i=1,j=2,交换nums[i]与nums[j];
然后,i继续向前寻找偶数,找到了2 ,i=2;
j继续向前寻找奇数,找到了3,j=1;
交换;
判断i与j的大小关系,退出while
输出是:1,2,3,4
其实这个地方遗漏掉了一个判断,那就是i永远要小于j;
因此,在i每一次移动的时候,都需要判断一次i<j;
同理,j亦是如此;
修改过后,就正确了;
#include <iostream>
#include <vector>
using namespace std;
vector<int> exchange(vector<int> &nums)
{
//双指针
//分别定义i j 指向数组的首尾两端,题目要求数组左边是奇数,右边是偶数
//所以,可以首先从左边找到第一个偶数,然后从右边找到第一个奇数,交换;直到最后,i==j结束遍历
//可以保证,i的左边都是奇数,j的右边都是偶数;
int i = 0, j = nums.size() - 1;
while (i <j)
{
while (nums[i] % 2 == 1 && i<j)
i++;
while (nums[j] % 2 == 0 && i<j)
j--;
std::swap(nums[i],nums[j]);
}
return nums;
}
int main()
{
vector<int> nums = {
1, 2, 3, 4};
nums=exchange(nums);
return 0;
}
这样便可以保证i<j;当i==j的时候,就是结束的时候;
还有
看见了双指针的标签,我以为这道题目要用链表来做:
那么看见复杂度 O(N);
时间复杂度: 两次遍历:
第一次遍历,构造奇偶链表;
第二次赋值:给数组重新赋值
swap 交换函数 ,存在于algorithm.h里面
刷题总结类 文章被收录于专栏
这里记录一些刷题时候的总结思考