数组元素按照奇偶性左右排列,记录一个错误!!!(力扣 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里面

刷题总结类 文章被收录于专栏

这里记录一些刷题时候的总结思考

全部评论

相关推荐

11-01 20:03
已编辑
门头沟学院 算法工程师
Amazarashi66:这种也是幸存者偏差了,拿不到这个价的才是大多数
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务