【算法练操】调整数组顺序使奇数位于偶数前面

399 阅读2分钟

题目:输入一个数组,实现一个函数来调整顺序,使奇数位于数组前半部分,偶数位于后半部分。

思路:总体划分查找的思想类似于快速排序,用两个指针,也就是两个哨兵,一头一尾部,尾部往前找直到找到奇数停下来,头部指针往后找直到找到偶数停下来,交换两数,接着循环,直到两指针重合。

/**
     * 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
     * 使得所有奇数位于数组的前半部分,所有偶数位予数组的后半部分。
     *
     * @param arr 输入的数组
     */
    public static void reorderOddEven(int[] arr) {
        // 对于输入的数组为空,或者长度小于2的只接返回
        if (arr == null || arr.length < 2) {
            return;
        }

        // 从左向右记录偶数的位置
        int start = 0;
        // 从右向左记录奇数的位置
        int end = arr.length - 1;
        // 开始调整奇数和偶数的位置
        while (start < end) {
            // 找偶数
            while (start < end && arr[start] % 2 != 0) {
                start++;
            }
            // 找奇数
            while (start < end && arr[end] % 2 == 0) {
                end--;
            }

            // 找到后就将奇数和偶数交换位置
            // 对于start=end的情况,交换不会产生什么影响
            // 所以将if判断省去了
            int tmp = arr[start];
            arr[start] = arr[end];
            arr[end] = tmp;
        }
    }

为了实现课扩展性,比较将所有负数排在非负数的前面,将被3整除的数排在不能被3整除的前面,很显然,这不是单个问题,这是一系列的问题,我们把解题思路分成两部分

  • 拆分数组的操作
  • 判断某个数是排在前面还是排在后面的标准
    public static void reorderOddEven(int[] arr) {
        // 对于输入的数组为空,或者长度小于2的只接返回
        if (arr == null || arr.length < 2) {
            return;
        }

        // 从左向右记录偶数的位置
        int start = 0;
        // 从右向左记录奇数的位置
        int end = arr.length - 1;
        // 开始调整奇数和偶数的位置
        while (start < end) {
        
           // 找奇数
            while (start < end && isEven(arr[end])) {
                end--;
            }
            // 找偶数
            while (start < end && !isEven(arr[start])) {
                start++;
            }

            // 找到后就将奇数和偶数交换位置
            // 对于start=end的情况,交换不会产生什么影响
            // 所以将if判断省去了
            int tmp = arr[start];
            arr[start] = arr[end];
            arr[end] = tmp;
        }
    }

    //我们只需修改这个就ok
   private boolean isEven(int n){
       return (n & 1) == 0
   } 
    

总结:这样就实现了解耦操作,对于一系列的问题,我们只需要修改判断操作,也就是编写类似于isEven函数即刻。==(n & 1) == 0 采用位运算判断奇偶效率好于加减乘除运算== ==,写代码的时候尽量用位运算,面试的时候也会让人赏心悦目。==