数据结构与算法之排序: Leetcode 922. 按奇偶排序数组 II (Typescript版)

按奇偶排序数组 II

描述

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

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

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

示例 1

复制代码
输入:nums = [4,2,5,7]
输出:[4,5,2,7]
解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。

示例 2

复制代码
输入:nums = [2,3]
输出:[2,3]

提示

  • 2 <= nums.length <= 2 * 1 0 4 10^4 104
  • nums.length 是偶数
  • nums 中一半是偶数
  • 0 <= numsi <= 1000

进阶

  • 可以不使用额外空间解决问题吗?

算法实现

1 )原生sort + 一般方法

js 复制代码
function sortArrayByParityII(nums: number[]): number[] {
    // 进行升序排序
    nums.sort((a, b) => a - b);
    // 声明一个空数组用来存储奇偶排序后的数组
    const res: number[] = [];
    // 记录奇数、偶数位下标
    let odd: number = 1;
    let even: number = 0;
    // 对数组进行遍历
    nums.forEach(item => {
        if (item % 2 === 1) {
            res[odd] = item;
            odd += 2;
        } else {
            res[even] = item;
            even += 2;
        }
    })
    return res;
};
  • 基于题目,我们需要知道,一半整数是奇数,另一半整数是偶数,可知,整个数组长度是偶数(数学基础)
  • 先整体排好序了,再基于原数组分别处理位置的问题,这里多使用了 res 的空间

2 )两次遍历 + & 运算判断奇偶对位存放

ts 复制代码
function sortArrayByParityII(nums: number[]): number[] {
    const ans: number[] = new Array(nums.length);
    let i: number = 0; // 默认i以0开始
    for (const x of nums) {
        if (!(x & 1)) {
            ans[i] = x;
            i += 2;
        }
    }
    i = 1; // 这里 i 从1开始
    for (const x of nums) {
        if (x & 1) {
            ans[i] = x;
            i += 2;
        }
    }
    return ans;
};
  • 这是官方提供方案,题目没有要求数组完全有序
  • 注意,"&"的运算方法:
    • 两个数值的个位分别相与,同时为1才得1,只要一个为0就为0。
    • 可以利用 & 的运算特性,来判断一个数是否为偶数。
    • 需要注意条件是 非负整数
  • 但是,这里仍然开辟了 新的 ans 数组空间

3 )双指针,奇偶交换

js 复制代码
function sortArrayByParityII(nums: number[]): number[] {
    const n: number = nums.length;
    let j: number = 1; // j奇数从1开始
    // i 索引从0开始,偶数,每次递增2,仍为偶数
    for (let i: number = 0; i < n; i += 2) {
        // i是偶数, 如果当前 nums[i] 是奇数, 注意,题目要求 nums[i] 最终也是偶数
        if (nums[i] & 1) {
            // 如果 nums[j]是奇数, j递增2,j仍旧奇数
            while (nums[j] & 1) {
                j += 2;
            }
            // 跳出while时, nums[j]为偶数了,交换 nums[i](当前奇数, 应为偶数) 和 nums[j](当前偶数, 应为奇数)
            [nums[i], nums[j]] = [nums[j], nums[i]];
        }
    }   
    return nums;
};
  • 这也是官方提供的一个解法,符合题意要求
  • 题目没有要求数组完全有序
  • 做题的步骤和思路都写在上面注释上了
相关推荐
Evand J几秒前
【MATLAB例程】三维RRT+APF路径规划与AOA-TDOA融合定位算法。附代码的下载链接
算法·matlab·路径规划·rrt·tdoa·apf·aoa
海绵宝宝转agent1 小时前
leetCode100算法开源笔记分享
笔记·算法
写后端的胖头鱼1 小时前
时间复杂度 & 空间复杂度
java·数据结构·算法·时间复杂度·空间复杂度
hahaha60161 小时前
黑体轨迹和色温--光源白点
人工智能·嵌入式硬件·算法·计算机视觉
海绵宝宝转agent1 小时前
基于Redis ZSet+AOP+注解实现限流注解算法
数据库·redis·算法
All for pursuit.2 小时前
【回溯-7】494.目标和
数据结构·c++·算法·leetcode
白杨尚青2 小时前
C++入门篇(十三):vector(上)——动态数组:构造、空间增长与迭代器失效
开发语言·c++·笔记·算法·stl
Jasmine_llq2 小时前
《P17461 [GESP202609 八级] 生成树计数》
算法·栈·tarjan 算法·边双连通分量·深度优先搜索 dfs·tarjan 保存当前路径节点·模乘法
Jasmine_llq2 小时前
《P17462 [GESP202609 八级] 末班车》
算法·dijkstra 算法·最大化版本,求最长可行值·建反向图(逆图 / 反转边)·多源 dijkstra 思想·对每个终点单独跑一遍djst·离线预处理 + 在线查询
the3clipse3 小时前
H.265熵编码核心:CABAC自适应二进制算术编码详解——如何将语法元素高效压缩为比特流
人工智能·算法·视频编码·h.265·hevc·cabac·cavlc