看评论区的大哥大姐提供的思路是:
 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里面

京公网安备 11010502036488号