LeetCode WiggleSort I && II

LeetCode Wiggle Sort I && II

 

public class WiggleSort {
	
	/*  Wiggle Sort I
		Given an unsorted array nums, reorder it in-place such that 
		nums[0] <= nums[1] >= nums[2] <= nums[3]....

		For example, given nums = [3, 5, 2, 1, 6, 4], one possible 
		answer is [1, 6, 2, 5, 3, 4].
	 */
	
	/*
	 *  Refer http://segmentfault.com/a/1190000003783283
	 *  Solution 1: Sort and two partition
	 *  Solution 2: Swap
	 */
	public void wiggleSortI(int[] nums) {
		if(nums == null || nums.length <= 1) return;
		
		int idx = 1;
		while(idx < nums.length) {
			if(idx % 2 == 0 && nums[idx] > nums[idx - 1]) { // nums[i] <= nums[i - 1]
				swap(nums, idx, idx - 1);
			} else if(idx % 2 == 1 && nums[idx] < nums[idx - 1]) { // nums[i] >= nums[i - 1]
				swap(nums, idx, idx - 1);
			}
			
			idx++;
		}
	}
	
	protected void swap(int[] nums, int i, int j) {
		int temp = nums[i];
		nums[i] = nums[j];
		nums[j] = temp;
	}
	
	
	
	/*
	leetcode Wiggle Sort II

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

	Example:
	(1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].
	(2) Given nums = [1, 3, 2, 2, 3, 1], 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?
	*/
			
	// refer: https://www.hrwhisper.me/leetcode-wiggle-sort-ii/
    public void wiggleSort(int[] nums) {
        if(nums == null || nums.length <= 1) return;
        
        int mid = (nums.length - 1) / 2; // 0 based index
        
        int midVal = findKthElement(nums, mid, 0, nums.length - 1);
        
        int small = mid, large = nums.length - 1;
        
        int[] temp = new int[nums.length];
        for(int i = 0; i < nums.length; i++) {
            if(i % 2 == 0) { // find next small
                int smallVal = nums[small--];
                temp[i] = smallVal;
            } else {
                int largeVal = nums[large--];
                temp[i] = largeVal;
            }
        }
        
        for(int i = 0; i < nums.length; i++) {
        	nums[i] = temp[i];
        }
    }
    
    protected int findKthElement(int[] nums, int k, int start, int end) {
        int partition = partition(nums, start, end);
        
        if(partition == k) 
            return nums[k];
        else if(partition < k) {
            return findKthElement(nums, k, partition + 1, end);
        } else {
            return findKthElement(nums, k, start, partition - 1);
        }
    }
    
    protected int partition(int[] nums, int start, int end) {
        int pivot = start + (int)((end - start) * Math.random());
        int pivotVal = nums[pivot];
        
        swap(nums, pivot, end);
        
        int pt = start;
        for(int i = start; i < end; i++) {
            if(nums[i] <= pivotVal) {
                swap(nums, i, pt);
                pt++;
            }
        }
        
        swap(nums, end, pt);
        
        return pt;
    }

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		WiggleSort so = new WiggleSort();
		
		int[] nums = {1,5,1,1,6,4 };
		
		so.wiggleSort(nums);
		
		for(int i : nums) {
			System.out.println(i + " ");
		}
	}

}

  

 

你可能感兴趣的:(LeetCode WiggleSort I && II)