public class Solution {
public void wiggleSort(int[] nums) {
if(nums == null || nums.length < 2) return;
boolean findBigger = true;
for(int i = 1; i < nums.length; i++){
if(findBigger){
if(nums[i] < nums[i - 1]){
swap(nums, i, i - 1);
}
} else {
if(nums[i] > nums[i - 1]){
swap(nums, i, i - 1);
}
}
findBigger = !findBigger;
}
}
private void swap(int[] nums, int a, int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
在 Wiggle Sort I 的基础上拿掉了等于号条件,整个题都 gay 了好多,因为这次如果相邻两个数是相等的,怎么 swap 都不符合题意。如果单纯的按顺序扫,就不可避免的会遇到到“找正确元素”的步骤,这个步骤一旦多了,复杂度就上去了。
先写个时间空间都各种不正确的写法,感受下思路。从后往前依次找剩余元素中最大的,按正序插入数组。
有的 test case 是【4,5,5,6】,属于"有重复元素" && "重复元素在第二次遍历插入" && "正好和前一轮结尾相邻" 的情况,所以都正序插入会出 bug.
public class Solution {
public void wiggleSort(int[] nums) {
if(nums == null || nums.length < 2) return;
Arrays.sort(nums);
int[] ans = new int[nums.length];
int index = nums.length - 1;
for(int i = 1; i < nums.length; index--){
ans[i] = nums[index];
i += 2;
}
for(int i = 0; i < nums.length; index--){
ans[i] = nums[index];
i += 2;
}
for(int i = 0; i < nums.length; i++){
nums[i] = ans[i];
}
}
}
public void wiggleSort(int[] nums) {
int median = findKthLargest(nums, (nums.length + 1) / 2);
int n = nums.length;
int left = 0, i = 0, right = n - 1;
while (i <= right) {
if (nums[newIndex(i,n)] > median) {
swap(nums, newIndex(left++,n), newIndex(i++,n));
}
else if (nums[newIndex(i,n)] < median) {
swap(nums, newIndex(right--,n), newIndex(i,n));
}
else {
i++;
}
}
}
private int newIndex(int index, int n) {
return (1 + 2*index) % (n | 1);
}