剑指offer

涉及的知识点

数组

题目描述

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

个人没看清题目版

由于眼拙,没看清最后一句话,所以写了一段仅仅调换位置的代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] reOrderArray (int[] array) {
        // write code here
        if(array.length<2) return array;
        int left = 0;
        int right = array.length-1;
        while(left<right){
            while(left<right&&array[left]%2!=0){
                left++;
            }
            while(left<right&&array[right]%2==0){
                right--;
            }
            
            int temp = array[left];
            array[left] = array[right];
            array[right] = temp;
        }
        
        return array;
    }
}

要是理解不了可以看下面这段

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *   
     *   初版
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] reOrderArray (int[] array) {
        // write code here
        if(array.length<2) return array;
        int left = 0;
        int right = array.length-1;
        while(left<right){
            if(array[left]%2==0&&array[right]%2==0){  //左右为偶
                left++;
                right--;
            }
            if(array[left]%2!=0&&array[right]%2==0){ //左为奇,右为偶
                right--;
            }
            if(array[left]%2!=0&&array[right]%2!=0){ //左为奇,右为奇
                left++;
            }
            if(array[left]%2==0&&array[right]%2!=0){ //左为偶,右为奇
                int temp = array[left];
                array[left]=array[right];
                array[right]=temp;
                left++;
                right--;
            }
        }
        
        return array;
    }
}

解题思路一

开辟一个新的数组,遍历元素组,将奇数放在新数组的前面,偶数放在后面。首先计数器num统计奇数的个数(一开始想的统计的偶数的个数结果出错了),然后遍历数组,奇数就从0开始放,偶数就从num位置开始。

错误代码

错误的原因就是统计了偶数的个数,当奇偶个数想等时,没啥问题,当奇数多时,就会出错,比如:
在这里插入图片描述
所以正确的应该是统计奇数的个数

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] reOrderArray (int[] array) {
        // write code here
        int[] temp = new int[array.length];
        int num = 0;
        for(int i=0;i<array.length;i++){
            if(array[i]%2==0){
                num++;            // 循环统计偶数的个数
            }
        }
       int i = 0,j=num;
        for(int k:array){   //遍历原数组
            if(k%2==0){
                temp[j++]=k;
            }else{
                temp[i++]=k;
            }
                
        }
        return temp;
    }
}

正确的代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
    public int[] reOrderArray (int[] array) {
        // write code here
        int[] temp = new int[array.length];
        int num = 0;
        for(int i=0;i<array.length;i++){
            if(array[i]%2 !=0){
                num++;            //循环统计偶数的个数
            }
        }
       int i = 0,j=num;
        for(int k:array){   //遍历原数组
            if(k%2==0){
                temp[j++]=k;
            }else{
                temp[i++]=k;
            }
                
        }
        return temp;
    }
}

复杂度分析

时间复杂度:O(N)
空间复杂度:O(N)

解题思路二

头尾指针,头指针找奇数,尾指针找偶数。然后插入新的数组中

出错代码

这里我将头尾指针的移动放在了交换之后,导致超时,思考以后发现无论是否发生交换指针都需要向后移动,所以应该放在外面。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
  public int[] reOrderArray (int[] array) {
        // write code here
        int[] num = new int[array.length];
        int head = 0;                  //原数组头指针
        int tail = array.length-1;      //原数组尾指针
        int left = head;               //新数组头指针
        int right = tail;               //新数组尾指针
        while(head<array.length && tail>=0){
            if(array[head]%2!=0){   //是奇数
                num[left]=array[head];
                left++;
                head++;
            }
             
            if(array[tail]%2==0){   //是偶数
                num[right]=array[tail];
                right--;
               tail--;
            }
        
        }
        
        return num;
    }
  
}

正确代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
  public int[] reOrderArray (int[] array) {
        // write code here
        int[] num = new int[array.length];
        int head = 0;                  //原数组头指针
        int tail = array.length-1;      //原数组尾指针
        int left = head;               //新数组头指针
        int right = tail;               //新数组尾指针
        while(head<array.length && tail>=0){
            if(array[head]%2!=0){   //是奇数
                num[left]=array[head];
                left++;
            }
             head++;
            if(array[tail]%2==0){   //是偶数
                num[right]=array[tail];
                right--;
            }
             tail--;
        }
        
        return num;
    }
  
}

复杂度分析

时间复杂度:O(N)
空间复杂度:O(N)

解题思路三

采用冒泡的方法,将奇数往前移动

代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param array int整型一维数组 
     * @return int整型一维数组
     */
  public int[] reOrderArray (int[] array) {
        // write code here
        int num = 0; //代表已经排好的奇数的个数
        for(int i=0;i<array.length;i++){
            if(array[i]%2==1){
                int j = i;
                while(j>num){  //循环将奇数前移
                    int temp = array[j];
                    array[j] = array[j-1];
                    array[j-1] = temp;
                    j--;
                }
                num++;  //循环一次,奇数排好的个数增加一个
            }
        }
      return array;
    }
  
}

复杂度分析

时间复杂度:O(N²)
空间复杂度:O(1)

总结

方便复习使用,如有错误欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值