922. 按奇偶排序数组 II

218 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情

题目 leetcode.cn/

  • 给定一个非负整数数组 nums,  nums 中一半整数是 奇数 ,一半整数是 偶数 。
  • 对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时, i 也是 偶数 。
  • 你可以返回 任何满足上述条件的数组作为答案 。

示例

  • 输入: nums = [4,2,5,7],输出:[4,5,2,7]

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

提示

  • 2 <= nums.length <= 200000
  • nums.length是偶数
  • nums中一半是偶数
  • 0 <= nums[i] <= 1000

代码

function sortArrayByParityII(nums: number[]): number[] {
    let odd = [];
    let even = [];
    for(let i = 0; i < nums.length; i++){
        if(nums[i] % 2){
            odd.push(nums[i]);
        }else{
            even.push(nums[i])
        }
    }
    let result = [];
    for(let i = 0; i< nums.length; i++){
        if(i % 2){
            result.push(odd.shift());
        }else{
            result.push(even.shift());
        }
    }
    return result;
};

思路

  • 将给定的数组按照下标的奇偶排序,可以先定义两个数组,一个存放奇数,一个存放偶数

    • 首先通过遍历数组,将原数组的奇数和偶数区分开来
    • 然后再次遍历循环,通过下标的奇偶性依次从奇数数组和偶数数组取出数字,添加到定义好的变量中保存
    • 返回交叉排序后的变量即可
  • 这样做循环两次,而且定义了新的空间变量,有一定内存开销。好在思路比较简单,容易想到

进阶: 可以不使用额外空间解决问题吗?

  • 不知道定义的中间保存变量算不算额外空间,应该也算,但是 内存消耗确实比上面一种更低,超过100%
function sortArrayByParityII(nums: number[]): number[] {
    for(let i = 0; i < nums.length; i+=2){
        if(nums[i] % 2){
            for(let j = 1; j < nums.length; j+=2){
                if(nums[j] % 2 === 0){
                    let temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                    break;
                }
            }
        }
    }
    return nums;
};
  • 简单说下思路:

    • 数组长度是偶数的,并且里面的数字奇偶数是相等的,那么一旦有一个偶数出现在奇数下标上,就一定会有一个奇数出现在偶数下标上与之对应
    • 那这样就简单了,遍历数组的每一个偶数下标项
      • 如果该偶数下标项上的数字是奇数,那么再次遍历数组的每一个奇数下标项,找到第一个奇数下标为偶数的,然后进行交换位置
      • 如果没有,那么整个数组就是按照奇偶排序的
  • 这一种写法只会在遇到错位的数字开始执行交换,没有错位的不会动,降低了内存消耗