剑指Offer-13-调整数组顺序是奇数位于偶数前面

题目

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

解析

这里其实牛客网把题目加强了,原书上是没有后面约束的,这时我们采用2个指针,一个指向数组开头,一个指向数组结尾,保证第一个指针永远指偶数,另一个指针永远指奇数,这样每交换一下,就把第一个指针向后移,第二指针向前,直到第一个指针不小于第二指针为止,此时表明第一个指针之前全是奇数,而第二指针之后都是偶数。

思路一

空间换时间的思路,利用辅助数组,扫描2次数组,一次存放所有的奇数,另一次存放所有的偶数,最后再把这些数重新写回原数组。

    /**
     * 笨方法,借助辅助空间
     * @param array
     */
    public static void reOrderArray1(int [] array) {
        int index = 0;
        int[] newArray = new int[array.length];
        for(int i = 0; i < array.length; i++) {
            if((array[i] & 1) == 1) {
                newArray[index++] = array[i];
            }
        }
        for(int i = 0; i < array.length; i++) {
            if((array[i] & 1) == 0) {
                newArray[index++] = array[i];
            }
        }
        System.arraycopy(newArray, 0, array, 0, array.length);
    }

思路二

插入排序的思想,从头开始遍历数组,若遇到奇数则把该数插入到它之前的序列中奇数后面。也就是说我们遇到奇数后,判断其前一个数是否是偶数,若是则交换位置,继续判断其前一个数是否是偶数,若是继续交换,直到走到数组开头或者前一个是奇数为止。我们这样的思想保证了交换过程中遇到的第一个奇数,即为数组前部分奇数序列的最后一个奇数。

    /**
     * 原址上操作,但是复杂度会较高
     * @param array
     */
    public static void reOrderArray2(int [] array) {
        for(int i = 0; i < array.length; i++) {
            if((array[i] & 1) == 1 && i != 0) {
                int index = i;
                while(index > 0 && (array[index - 1] & 1) != 1) {
                    int temp = array[index];
                    array[index] = array[index - 1];
                    array[index - 1] = temp;
                    index--;
                }
            }
        }
    }

你可能感兴趣的:(剑指Offer,不刷题心里难受)