【剑指offer】——剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

发布于:2022-11-28 ⋅ 阅读:(309) ⋅ 点赞:(0)

【剑指offer】——剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

👀先看这里👈
😀作者:江不平
📖博客:江不平的博客
📕学如逆水行舟,不进则退
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
❀本人水平有限,如果发现有错误的地方希望可以告诉我,共同进步👍

🔍题目详情

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。并且保证奇数和奇数,偶数和偶数的相对位置不变。

示例

输入:nums = [1,2,3,4]
输出:[1,3,2,4]

题目来源:[力扣(LeetCode)]

🤔解题思路

逻辑&步骤
删除线的内容作为拓展,先不看删除线的内容,不考虑相对顺序题目就变得简单起来,可以采用前后双指针的方法。两头开始遍历,头指针遇到奇数,尾指针遇到偶数,二者进行交换。

时间复杂度 :O(N)
空间复杂度 :O(1)

再看拓展后的题目,这里我们从头开始遍历数组,遇到奇数就保存下来,偶数往后移,再把奇数往前放,详见代码

时间复杂度 :O(N)
空间复杂度 :O(1)

💻代码实现

c++

class Solution {
public:
    vector<int> exchange(vector<int>& nums)
    {
        int i = 0, j = nums.size() - 1;
        while (i < j)
        {
            while(i < j && (nums[i] & 1) == 1) i++;
            while(i < j && (nums[j] & 1) == 0) j--;
            swap(nums[i], nums[j]);
        }
        return nums;
    }
};

扩展题目解法:
c++
奇数前插的过程,还有偶数后插,这里就不写了

class Solution {
public:
    vector<int> exchange(vector<int>& nums) {
        int k = 0;
		for (int i = 0; i < nums.size(); ++i) {
			if (nums[i] & 1) { //从左向右,每次遇到的,都是最前面的奇数,一定将来要被放在k下标处
				int temp = nums[i]; //现将当前奇数保存起来
				int j = i;//j代表的是当前奇数的位置
				while (j > k) { //将该奇数之前的内容(偶数序列),整体后移一个位置,这里不能是=,移动的次数是一定的。
					nums[j] = nums[j - 1];
					j--;
				} nums[k++] = temp; //将奇数保存在它将来改在的位置,因为我们是从左往右放的,没有跨越奇数,所以一定是相对位置不变的
			}
		}
        return nums;
    }
};

💬总结

  1. 决定一个数是奇偶,就二进制而言,就看第一个位置,因为其他位置都可以看成2的n次方。
  2. 注意循环的次数,这里的k,在写while循环时,逻辑上说第一次k确实为0,指的是数组的第一个位置,但是我们要考虑循环的次数,如果加了=,就会多循环一次,开区间是很容易看出来循环次数的,可读性强,一般用开区间。
  3. 这个题目较为简单,笔试中不常见,不过往往简单的这种题目拓展性很强,可以不断往外拓展,所以面试容易遇到。

在这里插入图片描述

觉得还不错的铁汁点赞关注一下吧😀