码迷,mamicode.com
首页 > 其他好文 > 详细

Wiggle Sort I & II

时间:2016-07-13 01:05:08      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

Given an unsorted array nums, reorder it in-place such that

nums[0] <= nums[1] >= nums[2] <= nums[3]....
 Notice

Please complete the problem in-place.

Example

Given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4].

分析:

排序,从第三个开始,把它和前一个数互换。

 1 public class Solution {
 2     /**
 3      * @param nums a list of integer
 4      * @return void
 5      */
 6     public void wiggleSort(int[] nums) {
 7         if (nums == null || nums.length <= 1) return;
 8         
 9         Arrays.sort(nums);
10         
11         for(int i = 2; i < nums.length; i+=2){
12             int tmp = nums[i-1];
13             nums[i-1] = nums[i];
14             nums[i] = tmp;
15         }
16     }
17 }

Given an unsorted array nums, reorder it such that

nums[0] < nums[1] > nums[2] < nums[3]....
 Notice

You may assume all input has valid answer.

Example

Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6].

Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2].

分析:

见solution.

 1 public class Solution {
 2     /**
 3      * @param nums a list of integer
 4      * @return void
 5      */
 6     public void wiggleSort(int[] nums) {
 7         if (nums == null || nums.length <= 1) return;
 8         Arrays.sort(nums);
 9         int[] temp = new int[nums.length];
10         
11         // 两个指针 p, q. p 指向中间那个数,q指向最右边那个数。
12         // 不断交替把数放在temp数组里。
13         int mid = (temp.length + 1) / 2 - 1;
14         int end = temp.length - 1;
15         
16         for (int i = 0; i < temp.length; i++) {
17             if ((i & 1) == 0) {
18                 temp[i] = nums[mid--];
19             } else {
20                 temp[i] = nums[end--];
21             }
22         }
23         
24         // put the numbers back to nums.
25         for (int i = 0; i < temp.length; i++) {
26             nums[i] = temp[i];
27         }
28         
29         // 
30         /*
31         下面这个方法是我最先的想法,但是通不过 1 1 2 2 3 3 这个case.
32         
33         int start = 1;
34         int end = nums.length - 1;
35         
36         if (nums.length % 2 == 0) {
37             end = nums.length - 2;
38         }
39         
40         while (start < end) {
41             int tmp = nums[start];
42             nums[start] = nums[end];
43             nums[end] = tmp;
44             start += 2;
45             end -= 2;
46         }
47         */
48     }
49 }

还有一种方法,先把array中的median找出来,然后把小于median和大于median的值交叉放入新数组中。

该方法来自: http://buttercola.blogspot.com/2016/01/leetcode-wiggle-sort-ii.html

 1 public class Solution {
 2     public void wiggleSort(int[] nums) {
 3         if (nums == null || nums.length <= 1) {
 4             return;
 5         }
 6          
 7         int n = nums.length;
 8          
 9         // Step 1: Find median of the array, return the index of the median
10         int median = findMedian(nums, 0, n - 1, (n - 1) / 2);
11          
12         // Step 2: 3-way sort, put median in the middle, 
13         // numbers less than median on the left, 
14         // numbers greater than median on the right
15         int[] temp = new int[n];
16         int left = 0;
17         int right = n - 1;
18          
19         for (int i = 0; i < n; i++) {
20             if (nums[i] < nums[median]) {
21                 temp[left] = nums[i];
22                 left++;
23             } else if (nums[i] > nums[median]) {
24                 temp[right] = nums[i];
25                 right--;
26             }
27         }
28          
29         // add median into the middle
30         for (int i = left; i <= right; i++) {
31             temp[i] = nums[median];
32         }
33          
34         // Step 3: wiggle sort
35         left = (n - 1) / 2;
36         right = n - 1;
37          
38         for (int i = 0; i < n; i++) {
39             if ((i & 1) == 0) {
40                 nums[i] = temp[left];
41                 left--;
42             } else {
43                 nums[i] = temp[right];
44                 right--;
45             }
46         }
47     }
48      
49     private int findMedian(int[] nums, int lo, int hi, int k) {
50         if (lo >= hi) {
51             return lo;
52         }
53          
54         int pivot = partition(nums, lo, hi);
55         if (pivot == k) {
56             return pivot;
57         }
58          
59         if (pivot > k) {
60             return findMedian(nums, lo, pivot - 1, k);
61         } else {
62             return findMedian(nums, pivot + 1, hi, k);
63         }
64     }
65      
66     private int partition(int[] nums, int lo, int hi) {
67         int pivot = nums[lo];
68         int i = lo + 1;
69         int j = hi;
70          
71         while (i <= j) {
72             while (i <= j && nums[i] < pivot) {
73                 i++;
74             }
75              
76             while (i <= j && nums[j] >= pivot) {
77                 j--;
78             }
79              
80             if (i <= j) {
81                 swap(nums, i, j);
82             }
83         }
84          
85         swap(nums, lo, j);
86          
87         return j;
88     }
89      
90     private void swap(int[] nums, int i, int j) {
91         int temp = nums[i];
92         nums[i] = nums[j];
93         nums[j] = temp;
94     }
95 }

 

Wiggle Sort I & II

标签:

原文地址:http://www.cnblogs.com/beiyeqingteng/p/5665380.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!