调整数组顺序使奇数位于偶数前面(剑指offer 21)Java双指针

简介: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。

一、题目描述



输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。


示例:

输入:nums = [1,2,3,4]

输出:[1,3,2,4]

注:[3,1,2,4] 也是正确的答案之一。


提示:

0 <= nums.length <= 50000

0 <= nums[i] <= 10000


二、思路讲解



借用快速排序的思想,用两个指针分别从头尾出发,左指针如果碰见奇数就继续往右,右指针如果碰见偶数就一直往左。当左指针碰到偶数、右指针碰到奇数时,交换两个指针的数,继续往中间寻找,知道两指针交汇。


三、Java代码实现



class Solution {
    public int[] exchange(int[] nums) {
        int i=0;
        int j=nums.length-1;
        while(i < j){
            //左指针找偶数,找到就跳出
            while(i<j && nums[i]%2!=0){
                i++;
            }
            //右指针找奇数,找到就跳出
            while(i<j && nums[j]%2==0){
                j--;
            }
            //交换两个指针的数
            int temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
            i++;
            j--;               
        }
        return nums;
    }
}


四、时空复杂度分析



时间复杂度        O(N)        

空间复杂度        O(1)


五、另一种双指针(效率较低)



class Solution {
    public int[] exchange(int[] nums) {
        int len = nums.length;
        if (len==0 || len==1){
            return nums;
        }
        int i = 0;
        int j = 1;
        while(i<len && j<len) {
            if(nums[i]%2 != 0){ //左指针为奇数
                i++;
                j++;
            } else {    //左指针为偶数
                if(nums[j]%2 != 0) { //左指针为偶数,右指针为奇数
                    int temp = nums[i];
                    nums[i] = nums[j];
                    nums[j] = temp;
                    i++;
                    j = i+1;
                } else {    //左指针为偶数,右指针为偶数
                    j++;
                }
            }
        }
        return nums;
    }
}



相关文章
|
7月前
|
Java
Java 数组学习笔记
本文整理Java数组常用操作:遍历、求和、查找、最值及二维数组行求和等典型练习,涵盖静态初始化、元素翻倍、去极值求平均等实例,帮助掌握数组基础与应用。
|
8月前
|
存储 缓存 Java
Java数组全解析:一维、多维与内存模型
本文深入解析Java数组的内存布局与操作技巧,涵盖一维及多维数组的声明、初始化、内存模型,以及数组常见陷阱和性能优化。通过图文结合的方式帮助开发者彻底理解数组本质,并提供Arrays工具类的实用方法与面试高频问题解析,助你掌握数组核心知识,避免常见错误。
|
9月前
|
存储 Java 索引
java 数组
在 Java 中,数组是一种数据结构,用于存储多个相同类型的数据元素。数组的大小一旦创建后就不能改变,因此它是固定长度的。Java 数组是一种 对象,即使它存储的值是基本类型(如 int、double 等),它也是一个对象引用。
211 0
|
11月前
|
存储 人工智能 Java
打乱数组内容引发的问题( Java)
本文介绍了两种实现数组随机打乱的方法,并深入探讨了Java中原始数据类型与对象类型的差异。方法一通过自定义随机数交换数组元素位置,方法二借助`Collections.shuffle()`函数完成数组打乱。同时,文章详细解析了`int`和`Integer`的区别,包括声明方式、内存占用、初始化以及对象特性等,并讲解了自动装箱与拆箱的功能,帮助读者更好地理解Java的基础知识。
172 0
|
12月前
|
存储 Java 数据挖掘
Java 中数组的多种定义方式
本文深入解析了Java中数组的多种定义方式,涵盖基础的`new`关键字创建、直接初始化、动态初始化,到多维数组、`Arrays.fill()`方法以及集合类转换为数组等高级用法。通过理论与实践结合的方式,探讨了每种定义方法的适用场景、优缺点及其背后的原理,帮助开发者掌握高效、灵活的数组操作技巧,从而编写更优质的Java代码。
607 0
|
人工智能 Java
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
898 1
Java 中数组Array和列表List的转换
运用双指针解决经典移除元素问题|Java 刷题打卡
运用双指针解决经典移除元素问题|Java 刷题打卡
|
6月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
295 1
|
6月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
314 1