LeetCode Wiggle Sort II

原题链接在这里:https://leetcode.com/problems/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?

题解:

先通过Kth Largest Element in an Array找出median.

再把小于median的放在low位, 大于median的放在high位.

When we assign value to low index and high index, we need to consider n is odd and even, 2 cases.

e.g. 44456, median is 4, final anser is 45464, we need to put high index as n - 2, and every time high -=2.

4556, median is 5, final asnwer is 5645, here we need to put low index as n - 2, and every time low -= 2. 

If for 4556, we also put high index as n - 2, we will get 5555 -> 4556, there are two 5 close to each other.

Note: eventually we need to assign res back to nums one by one, but not nums = res. Since it is checking heap, but not stack. nums is a variable in stack, it is pointing to realy memory in heap.

Time Complexity: O(n). Space: O(n).

AC Java:

 1 class Solution {
 2     public void wiggleSort(int[] nums) {
 3         if(nums == null || nums.length < 2){
 4             return;
 5         }
 6         
 7         int n = nums.length;
 8         int median = findK(nums, 0, n - 1, n / 2);
 9         int [] res = new int[n];
10         Arrays.fill(res, median);
11         
12         if(n % 2 == 1){
13             int low = 0;
14             int high = n - 2;
15 
16             for(int num : nums){
17                 if(num < median){
18                     res[low] = num;
19                     low += 2;
20                 }else if(num > median){
21                     res[high] = num;
22                     high -= 2;
23                 }
24             }
25         }else{
26             int low = n - 2;
27             int high = 1;
28             for(int num : nums){
29                 if(num < median){
30                     res[low] = num;
31                     low -= 2;
32                 }else if(num > median){
33                     res[high] = num;
34                     high += 2;
35                 }
36             }
37         }
38         
39         
40         for(int i = 0; i < n; i++){
41             nums[i] = res[i];
42         }
43     }
44     
45     private int findK(int [] nums, int l, int r, int k){
46         if(l >= r){
47             return nums[l];   
48         }
49         
50         int m = partition(nums, l, r);
51         if(m == k){
52             return nums[m];
53         }else if(m < k){
54             return findK(nums, m + 1, r, k);
55         }else{
56             return findK(nums, l, m - 1, k);
57         }
58     }
59     
60     private int partition(int [] nums, int l, int r){
61         int pivot = nums[l];
62         while(l < r){
63             while(l < r && nums[r] >= pivot){
64                 r--;
65             }
66             
67             nums[l] = nums[r];
68             
69             while(l < r && nums[l] <= pivot){
70                 l++;
71             }
72             
73             nums[r] = nums[l];
74         }
75         
76         nums[l] = pivot;
77         return l;
78     }
79 }

类似Wiggle Sort

posted @ 2016-02-12 00:17  Dylan_Java_NYC  阅读(709)  评论(0编辑  收藏  举报