算法的学习笔记—调整数组顺序使奇数位于偶数前面

举报
尘觉 发表于 2024/08/15 13:06:05 2024/08/15
【摘要】 在数据处理和算法问题中,经常需要对数组进行特定的调整或排序。本文将介绍如何调整一个整数数组的顺序,使得所有的奇数位于数组的前半部分,而所有的偶数位于数组的后半部分,并且保持奇数和奇数、偶数和偶数之间的相对顺序不变。

😀前言
在数据处理和算法问题中,经常需要对数组进行特定的调整或排序。本文将介绍如何调整一个整数数组的顺序,使得所有的奇数位于数组的前半部分,而所有的偶数位于数组的后半部分,并且保持奇数和奇数、偶数和偶数之间的相对顺序不变。

😀调整数组顺序使奇数位于偶数前面

题目链接

牛客网

😁题目描述

输入一个长度为 n 整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

数据范围:0≤n≤5000,数组中每个数的值 0≤val≤10000

要求:时间复杂度 O(n),空间复杂度 O(n)

进阶:时间复杂度 O(n^2^),空间复杂度 O(1)

😍示例

示例1

输入:[1,2,3,4]
返回值:[1,3,2,4]

示例2

输入:[2,4,6,5,7]
返回值:[5,7,2,4,6]

示例3

输入:[1,3,5,6,7]
返回值:[1,3,5,7,6]

需要保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。例如对于 [1,2,3,4,5],调整后得到 [1,3,5,2,4],而不能是 {5,1,3,4,2} 这种相对位置改变的结果。

image.png

🥰解题思路

💓题思路

为了解决这个问题,有两种常见的方法:使用额外的空间创建新数组,或在原数组上进行调整。下面将详细介绍这两种方法。

💞方法一:使用额外空间

通过使用额外的空间,可以在O(n)的时间复杂度内完成调整,同时保持原有的相对顺序。

💕步骤:
  1. 遍历数组,统计奇数的个数,并创建一个与原数组大小相同的副本。
  2. 重新遍历数组,将奇数按顺序放在副本的前半部分,偶数放在副本的后半部分。
  3. 将副本中的元素按顺序放回原数组。

❤️‍🔥代码实现:

public int[] reOrderArray (int[] nums) {
    // 奇数个数
    int oddCnt = 0;
    for (int x : nums)
        if (!isEven(x))
            oddCnt++;
    int[] copy = nums.clone();
    int i = 0, j = oddCnt;
    for (int num : copy) {
        if (num % 2 == 1)
            nums[i++] = num;
        else
            nums[j++] = num;
    }
    return nums;
}

private boolean isEven(int x) {
    return x % 2 == 0;
}

分析

  • 时间复杂度:O(n),遍历数组两次。
  • 空间复杂度:O(n),因为需要额外的空间来存储副本。

💞方法二:原地调整

如果对空间复杂度有更高的要求,可以选择在原数组上进行调整。我们可以借助冒泡排序的思想,每次将当前的偶数向后交换,直至它被排到最后一位。

💕步骤:

  1. 从右向左遍历数组,每次遇到偶数时,将其与后面的元素交换,直至它后面紧跟的元素为奇数。
  2. 重复上述操作,直到所有的偶数都排到数组的右端。

❤️‍🔥代码实现:

public int[] reOrderArray(int[] nums) {
    int N = nums.length;
    for (int i = N - 1; i > 0; i--) {
        for (int j = 0; j < i; j++) {
            if (isEven(nums[j]) && !isEven(nums[j + 1])) {
                swap(nums, j, j + 1);
            }
        }
    }
    return nums;
}

private boolean isEven(int x) {
    return x % 2 == 0;
}

private void swap(int[] nums, int i, int j) {
    int t = nums[i];
    nums[i] = nums[j];
    nums[j] = t;
}

分析:

  • 时间复杂度:O(n^2),因为需要进行多次遍历和交换操作。
  • 空间复杂度:O(1),没有使用额外的空间。
  • 时间换空间

😄比较与总结

这两种方法各有优缺点。如果需要快速调整且不在意空间开销,可以选择方法一,它在O(n)的时间内完成排序。而如果对空间复杂度要求更高,可以选择方法二,它在原数组上操作,但需要O(n^2)的时间。

在实际应用中,可以根据具体需求选择合适的方法。如果数组较小且对空间要求严格,方法二可能更合适;如果数组较大且需要更快的处理速度,方法一是更优的选择。

通过这两种方法,我们可以有效地调整数组中的奇偶顺序,满足特定的排序需求。这种调整方式在数据处理、算法设计中有着广泛的应用,掌握这些技巧可以为解决复杂问题提供思路和方法。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。