思路:
1)QucikSort 的方法找出中间值,时间O(n),空间O(1)
2)参见参考链接,类似于给三种颜色排序,将高中低三种值各自规划成一组,由于其中涉及到数组索引的变换,使得实际得到的结果是高低穿插。例如:
数组值:高 高 高 中 中 低
原索引: 0 1 2 3 4 5
变换后: 3 0 4 1 5 2
依据变换索引给高中低值进行规划(顺序为高中低):
变换后索引值: 0 1 2 3 4 5
数 组 值:高 高 高 中 中 低
原 索 引: 1 3 5 0 2 4
也就是
原 索 引: 0 1 2 3 4 5
数 组 值:中 高 中 高 低 中
这个方法的另一个好处是变换后中间值是相邻的,使得变换前中间值是岔开的,解决了[4, 5 , 5, 6]这种情况
时间O(n),空间O(1)
代码:
public class Solution { public void wiggleSort(int[] nums) { if (nums == null || nums.length <= 1) return; int median = getMedian(nums); int higher = 0, lower = nums.length - 1, current = 0; while (current <= lower) { if (nums[reIndex(current, nums.length)] == median) { current++; } else if (nums[reIndex(current, nums.length)] < median) { swap(nums, reIndex(current, nums.length), reIndex(lower--, nums.length)); } else swap(nums, reIndex(current++, nums.length), reIndex(higher++, nums.length)); } } private int reIndex(int index, int n) { return (2*index + 1) % (n | 1); } private int getMedian(int[] nums) { int start = 0, end = nums.length - 1, target = nums.length / 2; while (true) { swap(nums, start, (start + end) / 2); int swapIndex = start, current = start + 1; while (current <= end) { if (nums[current] >= nums[start]) swap(nums, ++swapIndex, current); current++; } swap(nums, start, swapIndex); if (swapIndex - start == target) return nums[swapIndex]; else if (swapIndex - start > target) end = swapIndex - 1; else { target -= (swapIndex - start + 1); start = swapIndex + 1; } } } private void swap(int[] nums, int index1, int index2) { int temp = nums[index1]; nums[index1] = nums[index2]; nums[index2] = temp; } }
No comments:
Post a Comment