1

Wiggle Sort

题目链接:https://leetcode.com/problems...

这道题允许等号,相对简单,有两种方法:1. sort然后交换奇数位和它下一位的元素,2. 不满足条件的时候直接交换

可以用递推来说明一下这么做的正确性:

  1. 假设到第i位之前都满足题目要求的关系

  2. 现在比较第i位和第i+1位

    • if i == odd:

      • nums[i] >= nums[i+1],到i+1位都满足条件

      • nums[i] < nums[i+1],swap(i, i+1),新的nums[i] >= nums[i+1] >= nums[i-1],所以到i+1都满足条件

    • if i == even:

      • 同理

  3. 一直递推到len(nums),所以整个数组都满足条件

public class Solution {
    public void wiggleSort(int[] nums) {
        /* condition: nums[odd] >= nums[even]
         * 1. sort => [1, 2, 3, 4, 5, 6] => swap(i, i+1)
         * 2. swap if a. nums[i] < nums[i+1] i = odd
         *            b. nums[i] > nums[i+1] i = even
         */
        for(int i = 0; i < nums.length - 1; i++) {
            if(i % 2 == 1 && nums[i] < nums[i+1]) swap(nums, i, i+1);
            if(i % 2 == 0 && nums[i] > nums[i+1]) swap(nums, i, i+1);
        }
    }
    
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

324. Wiggle Sort II

题目链接:https://leetcode.com/problems...

这题不能有等号,而且要求O(N)的时间和O(1)的空间,那么感觉只能quick select了。如果没复杂度的要求,先sort也可以,再交叉放入数字也可以。交叉的时候注意是按照[2, 0, 3, 1],降序的。

public class Solution {
    public void wiggleSort(int[] nums) {
        /* quick select: find the middle element
         * 3 way partitions: [h, l, ...]
         * [2, 0, 3, 1], [2, 0, 3, 1, 4]
         */
         n = nums.length;
         int mid = quickSelect(nums, 0, nums.length - 1, nums.length / 2);
         partition(nums, 0, nums.length - 1, mid);
    }
    
    int n;
    private void partition(int[] nums, int l, int r, int mid) {
        int i = l;
        while(i <= r) {
            if(nums[mapping(i)] > mid) swap(nums, mapping(i++), mapping(l++));
            else if(nums[mapping(i)] < mid) swap(nums, mapping(i), mapping(r--));
            else i++;
            
        }
    }
    
    private int mapping(int i) {
        return (2 * i + 1) % (n | 1);
    }
    
    private int quickSelect(int[] nums, int l, int r, int k) {
        if(l >= r)  return nums[l];
        
        int pivot = nums[r];
        int index = l;
        for(int i = l; i < r; i++) {
            if(nums[i] < pivot) swap(nums, i, index++);
        }
        // swap the pivot to the correct position
        swap(nums, index, r);
        if(index == k) return nums[index];
        else if(index < k) return quickSelect(nums, index + 1, r, k);
        else return quickSelect(nums, l, index - 1, k);
    }
    
    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

lulouch13
13 声望6 粉丝