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?

Solution

public class Solution {

    int n;
    public void wiggleSort(int[] nums) {
        n = nums.length;
        int median = getMedian(nums);
        // three way partition based on index mapping
        int i = 0, j = 0, k = n - 1;
        while(j <= k) {
            // we examine each j
            if(nums[mapping(j)] < median) {
                swap(nums, mapping(j), mapping(i));
                j++;
                i++;
            } else if(nums[mapping(j)] > median) {
                swap(nums, mapping(j), mapping(k));
                k--;
            } else {
                j++;
            }
        }

    }

    public int mapping(int i) {
        if(i < (n+1)/2) return n % 2 == 0 ? n - 2 * i - 2 : n - 2 * i - 1;
        else return (2 * n - 2 * i - 1);
    }

    public void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

    public int getMedian(int[] nums) {
        int k = nums.length / 2;

        int l = 0;
        int r = nums.length - 1;
        int idx = partition(nums, l, r);
        while(idx != k) {
            if(idx > k) {
                r = idx - 1;
            } else {
                l = idx + 1;
            }
            idx = partition(nums, l, r);
        }
        return nums[idx];
    }

    public int partition(int[] nums, int l, int r) {
        if(l == r) return l;

        int pivot = nums[r];
        int pos = l; // every element before pos is < pivot
        for(int i = l; i <= r; i++) {
            if(nums[i] < pivot) {
                swap(nums, pos++, i);
            }
        }
        swap(nums, pos, r);
        return pos;
    }
}

results matching ""

    No results matching ""