1. 程式人生 > >Leetcode 324 Wiggle Sort II

Leetcode 324 Wiggle Sort II

題目描述

Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]…

Example 1:

Input: nums = [1, 5, 1, 1, 6, 4]
Output: One possible answer is [1, 4, 1, 5, 1, 6].
Example 2:

Input: nums = [1, 3, 2, 2, 3, 1]
Output: One possible answer is [2, 3, 1, 3, 1, 2].
Note:
You may assume all input has valid answer.

Follow Up:
Can you do it in O(n) time and/or in-place with O(1) extra space?

解題思路

此題是多路排序的變種,在多路排序中,我們會分為大於key,等於key和小於key三部分,這題我們也仿照此思路。首先我們求出中位數後面簡稱mid ,因為輸入的資料保證有結果,所以輸入陣列必滿足:
陣列中大於mid的數量為n/2,比如:n=5,那麼有2個元素大於mid;如果n=6,那麼有3個元素大於mid。所以我們設計演算法的時候保證位置1,3,5,7…的位置大於mid,同時2,4,6,8…的位置小於等於mid即可。在演算法實現上很像快排的partition操作。下面給出程式碼:

public class WiggleSort {

    public void wiggleSort(int[] nums) {
        if (nums==null || nums.length==0) {
            return;
        }
        int n = nums.length;
        int i=0,j=0,k=n-1;
        int mid = getMid(nums,(n+1)/2,0,n-1);
        print(nums);
        //System.out.println("start to compute!");
        while (i<=k) {
            if (nums[index(i,n)] > mid) {
                swap(nums,index(i,n),index(j,n));
                i++;
                j++;
            } else if(nums[index(i,n)] < mid) {
                swap(nums,index(i,n),index(k,n));
                k--;
            } else {
                i++;
            }
            //print(nums);
        }
        System.out.println("final result : ");
        print(nums);
    }

    void print(int[] nums) {
        for(int n : nums) {
            System.out.print(n+",");
        }
        System.out.println();
    }

    int getMid(int[]a,int mid,int start,int end) {
        int key = a[start];
        int j = start-1;
        for(int i=start;i<=end;i++) {
            if(a[i] <= key) {
                swap(a,i,++j);
            }
        }
        swap(a,start,j);
        int count = j-start + 1;
        if (count==mid) {
            return key;
        } else if (count > mid) {
            return getMid(a,mid,start,j-1);
        } else {
            return getMid(a,mid - count,j+1,end);
        }
    }

    int index(int i,int n) {
        return (i*2+1) % (n|1);
    }

    void swap(int[]nums,int i,int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

    public static void main(String[]args) {
        WiggleSort wiggleSort = new WiggleSort();
        int [] nums = new int[]{1};
        int mid = wiggleSort.getMid(nums,(nums.length + 1)/2,0,nums.length-1);
        System.out.println("mid : " + mid);
        wiggleSort.wiggleSort(nums);
    }
}