【力扣刷题】922. 按奇偶排序数组 II 【双指针】

648 阅读1分钟

「这是我参与11月更文挑战的第 12 天,活动详情查看:2021最后一次更文挑战

原题链接

922. 按奇偶排序数组 II - 力扣(LeetCode) (leetcode-cn.com)

题目描述

给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。

对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。

你可以返回任何满足上述条件的数组作为答案。

测试用例

示例:

输入:[4,2,5,7]
输出:[4,5,2,7]
解释:[4,7,2,5][2,5,4,7][2,7,4,5] 也会被接受。

参数限制

  • 2 <= A.length <= 20000
  • A.length % 2 == 0
  • 0 <= A[i] <= 1000

分析

已知一个数组 A,其中的元素为成对的奇偶数,需要我们将整个数组调整为奇数偶数交叉的格式,其中,对数值的顺序不做要求

最简单的办法,就是遍历 A,用两个变量分别存储奇数偶数,然后再像编麻花一样将奇数和偶数组合到情况的 A 数组中

代码

var sortArrayByParityII = function(nums) {
    let a=[],b=[];
    nums.forEach(n=>{
        if(n%2==0){
            b.push(n)
        }else{
            a.push(n)
        }
    })
    nums = [];
    a.forEach((n,i)=>{
        nums.push(b[i],n)
    })
    return nums;
};

image.png

这个简单的方案有 2 个缺点:

  1. 总共需要遍历 (1 + 1/2) * A.length
  2. 使用了额外的空间,指我们需要使用2个新的数组(分别存储奇偶数)

双指针优化

题目要求数组格式为奇偶数间隔,并且偶数开头,那么我们定义两个指针

  1. 偶数指针 a 指向 index=0,奇数指针 b 指向 index=1

  2. 遍历数组,当 a 找到一个非偶数,停下;当 b 找到一个非奇数,停下

  3. a,b 指针交换数据

  4. 交互完成后,a,b 指针同时向后移动 2 步,继续遍历数组

var sortArrayByParityII = function(nums) {
    for (let a = 0, b = 1; a < nums.length&& b < nums.length;) {
        if (a % 2 == 0) {
            a += 2;
            continue;
        }
        if (b % 2 == 1) {
            b += 2;
            continue;
        }
        console.log(a,b)
        let c = nums[a];
        nums[a] = nums[b];
        nums[b] = c;
        a += 2;
        b += 2;
    }
    return nums;
};

image.png

从性能对比来看双指针解法有了很大的提高


今天的力扣刷题就分享到这里,感谢大家的阅读~