【一刷《剑指Offer》】面试题 14:调整数组顺序使奇数位于偶数前面

力扣对应题目链接:LCR 139. 训练计划 I - 力扣(LeetCode)

牛客对应题目链接:调整数组顺序使奇数位于偶数前面(二)_牛客题霸_牛客网 (nowcoder.com)

核心考点**:数组操作,排序思想的扩展使用。**


一、《剑指Offer》对应内容


二、分析题目

按照题目意思,其实跟快排的思路一致,我们只需要定义双指针 left 和 right 分别指向数组的第一个元素和最后一个元素,接着让 left 往后遍历,直到找到前半部分的第一个偶数,让 right 向前遍历,直到找到后半部分的第一个奇数,然后交换 left 和 right 所在位置的数即可,遍历后的数组就是我们要的答案。


扩展:假设现在新增需求,需要保证奇数和奇数,偶数和偶数之间的相对位置不变。

解决这个问题的方法也比较多,这里我们采用较优方式解决一下,借鉴插入排序 的思想。做法:从左向右遍历,每次遇到的都是最前面的奇数,将该奇数之前的内容(偶数序列)整体后移一个位置,腾出位置后,将奇数保存在它将来该在的位置,因为我们是从左往右放的,没有跨越奇数,所以一定是相对位置不变的。


三、代码(C++)

1、方法一(头尾双指针法)

cpp 复制代码
//写法一
class Solution {
public:
    vector<int> trainingPlan(vector<int>& actions) {
        int n=actions.size();
        int left=0, right=n-1;
        while(left<right)
        {
            while(left<right && actions[left]%2==1)
                left++;
            while(left<right && actions[right]%2==0)
                right--;
            if(left<right)
                swap(actions[left], actions[right]);
        }
        return actions;
    }
};

//写法二
class Solution {
public:
    vector<int> trainingPlan(vector<int>& actions) {
        int n=actions.size();
        int left=0, right=n-1;
        while(left<right)
        {
            while(left<right && (actions[left]&1))
                left++;
            while(left<right && !(actions[right]&1))
                right--;
            if(left<right)
                swap(actions[left], actions[right]);
        }
        return actions;
    }
};
cpp 复制代码
//牛客网
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型vector 
     * @return int整型vector
     */
    vector<int> reOrderArrayTwo(vector<int>& array) {
        int n=array.size();
        int left=0, right=n-1;
        while(left<right)
        {
            while(left<right && array[left]%2==1)
                left++;
            while(left<right && array[right]%2==0)
                right--;
            if(left<right)
                swap(array[left], array[right]);
        }
        return array;
    }
};

2、方法二(插入法-保证相对顺序不变)

cpp 复制代码
class Solution {
public:
    vector<int> trainingPlan(vector<int>& actions) {
        int n=actions.size();
        int k=0; //记录已排好序的奇数个数
        for(int i=0; i<n; i++)
        {
            if(actions[i]%2==1)
            {
                int tmp=actions[i]; //先将当前奇数保存起来
                int j=i;
                while(j>k)
                {
                    actions[j]=actions[j-1];
                    j--;
                }
                actions[k++]=tmp; //将奇数保存在它将来该在的位置
            }
        }
        return actions;
    }
};
相关推荐
裕晟资质规划2 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法
en.en..3 小时前
C语言 标准输入 / 输出缓冲区
算法
吃好睡好便好5 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学习星球5 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
靠沿6 小时前
贪心算法专题(二)
算法·贪心算法
布莱克6056 小时前
数组详解:定义、作用、应用场景及与链表的区别(C/C++ 代码讲解)
c语言·开发语言·c++·数组
猎头南楼7 小时前
具身智能模型部署方向的能力要求与技术栈梳理
人工智能·深度学习·算法
啥都想学点的研究生8 小时前
一篇文章讲清楚:线性回归问题的求解——正规方程法
算法·机器学习·线性回归
青少儿编程课堂8 小时前
树状数组精讲:逆序对计数与离散化(附双语言解法)
算法·树状数组·离散化·信息学奥赛·逆序对
血小板要健康8 小时前
网格 dfs 与 FloodFill:从岛屿、区域到搜索路径
笔记·算法·leetcode·深度优先