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

😀前言

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

🏠个人主页:尘觉主页

文章目录

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

题目链接

牛客网

😁题目描述

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

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

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

进阶:时间复杂度 O(n2),空间复杂度 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连支持一下,创造不易您们的支持是我的动力🤞

相关推荐
绵绵细雨中的乡音19 分钟前
Linux进程学习【基本认知】
linux·运维·学习
知来者逆21 分钟前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
时间之城24 分钟前
笔记:记一次使用EasyExcel重写convertToExcelData方法无法读取@ExcelDictFormat注解的问题(已解决)
java·spring boot·笔记·spring·excel
阿让啊26 分钟前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
এ᭄画画的北北26 分钟前
力扣-160.相交链表
算法·leetcode·链表
灏瀚星空32 分钟前
用Obsidian四个插件打造小说故事关联管理系统:从模板到图谱的全流程实践
经验分享·笔记·开源
一只可爱的小猴子1 小时前
2022李宏毅老师机器学习课程笔记
人工智能·笔记·机器学习
孞㐑¥1 小时前
C++11介绍
开发语言·c++·经验分享·笔记
爱研究的小陈1 小时前
Day 3:数学基础回顾——线性代数与概率论在AI中的核心作用
算法
使一颗心免于哀伤1 小时前
《重构》笔记摘录 - 9.处理继承关系
笔记