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

本文探讨了在不改变奇数和偶数内部顺序的前提下,将整数数组中的所有奇数移动到前面,所有偶数移动到后面的问题。介绍了三种解决方案:顺次移动、冒泡算法和使用辅助空间的方法,详细解析了每种方法的实现步骤和复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

首先我们先分析一下题干,奇数和奇数之间,偶数和偶数之间的相对位置不变,所以要保证排序具有稳定性,而具有稳定性的排序有:插入,归并,冒泡排序,这是我们可以可以采用的排序方法。而快速排序和选择排序是不稳定的,所以不能用这两种方法来排序。

1.如果考虑不借用辅助空间的话,我们可以选择顺次移动或者相邻交换的方法,此时空间复杂度为O(1),时间复杂度较大为O(n2)。

下面我们先来看一下如何用顺次移动的方法来解决这个问题:

public class Solution {
    public void reOrderArray(int [] array) {
    	//判断数组是否为空或是否长度为0
    	//数组等于null代表空指针,不指向任何对象
    	//长度为0的数组,指向内存中一个长度为零的数组可以进行add操作
        if(array==null||array.length==0){
            return;
        }
        int i=0,j;
        while(i<array.length){
        	//找到数组中的第一个偶数
            while(i<array.length&&!isEven(array[i])){
                i++;
            }
            j=i+1;
            //找到偶数后的第一个奇数
            while(j<array.length&&isEven(array[j])){
                j++;
            }
            //将i->j-1中的数往后移 一位i+1->j
            //将原下标为j的数组元素值赋给i
            if(j<array.length){
                int temp = array[j];
                for(int k=j-1;k>=i;k--){
                    array[k+1]=array[k];
                }
                array[i++]=temp;
            }
            else{
                break;
            }
        }
    }
    
	//判断一个整数是否为偶数    
    public boolean isEven(int a){
        if(a%2==0){
            return true;
        }
        return false;
    }
}

冒泡算法解决此问题(即相邻交换):

//对于这个算法有疑问,大家可以去看下冒泡算法的原理和相关代码
public class Solution {
    public void reOrderArray(int [] array) {
        if(array==null||array.length==0){
            return;
        }
        int temp;
        for(int i=0;i<array.length-1;i++){
            for(int j=0;j<array.length-i-1;j++){
                if(array[j]%2==0&&array[j+1]%2!=0){
                    temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }
            }
        }
    }
}

2.借助辅助空间解决此问题:借助辅助空间可以减小程序复杂度,其实是以空间换时间的方式来解决此问题。
大家最容易想到的应该就是这种方法:创建两个ArrayList,然后遍历原数组,把奇数和偶数分别存在两个链表中,然后合并赋值给原数组。这样虽然思路很清晰,可读性好,但是空间复杂度比较高。

下面我来推荐一个只用添加一个新数组就能完成此问题的方法。
时间复杂度:O(n),空间复杂度:O(n)

//这是一个典型的用空间换时间的方法
public class Solution {
    public void reOrderArray(int [] array) {
        if(array==null||array.length==0) return;
        int oddCount=0;
        int odd=0;
        int[] newArr = new int[array.length];
        //计算原数组中奇数的数量
        for(int i=0;i<array.length;i++){
            if((array[i]&1)==1){
                oddCount++;
            }
        }
        for(int j=0;j<array.length;j++){
            if((array[j]&1)!=0){
            	//从零开始把奇数赋值到新数组中
                newArr[odd++]=array[j];
            }
            else{
            	//从第oddCount个把偶数赋值到新数组中
                newArr[oddCount++]=array[j];
            }
        }
        for(int k=0;k<array.length;k++){
        	//最后只需要把整个新数组赋值给原数组即可
            array[k]=newArr[k];
        }
    }
}

这个方法用时较短,且稳定,在要求时间复杂度的情况下,是一种很好的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值