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

😀前言

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

🏠个人主页:尘觉主页

文章目录

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

题目链接

牛客网

😁题目描述

输入一个长度为 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} 这种相对位置改变的结果。

🥰解题思路

💓题思路

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

💞方法一:使用额外空间

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

💕步骤:
  1. 遍历数组,统计奇数的个数,并创建一个与原数组大小相同的副本。
  2. 重新遍历数组,将奇数按顺序放在副本的前半部分,偶数放在副本的后半部分。
  3. 将副本中的元素按顺序放回原数组。
❤️‍🔥代码实现:
java 复制代码
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. 重复上述操作,直到所有的偶数都排到数组的右端。
❤️‍🔥代码实现:
java 复制代码
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)的时间。

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

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

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁

希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻

如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

相关推荐
XH华18 分钟前
初识C语言之二维数组(下)
c语言·算法
南宫生40 分钟前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
不想当程序猿_1 小时前
【蓝桥杯每日一题】求和——前缀和
算法·前缀和·蓝桥杯
sanguine__1 小时前
Web APIs学习 (操作DOM BOM)
学习
落魄君子1 小时前
GA-BP分类-遗传算法(Genetic Algorithm)和反向传播算法(Backpropagation)
算法·分类·数据挖掘
冷眼看人间恩怨1 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
菜鸡中的奋斗鸡→挣扎鸡1 小时前
滑动窗口 + 算法复习
数据结构·算法
Lenyiin1 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
郭wes代码1 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
scan7242 小时前
LILAC采样算法
人工智能·算法·机器学习