Wiggle Sort II

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?

Credits:Special thanks to @dietpepsi for adding this problem and creating all test cases.

Solution

public class Solution {
    public void wiggleSort(int[] nums) {
        if (nums == null || nums.length <= 1) return;

        int size = nums.length;
        int medium = medium(nums);
        int[] newArray = new int[size];
        for (int i = 0; i < size; i++) {
            newArray[i] = medium;
        }

        if (size % 2 == 0) {
            int l = nums.length - 2;
            int r = 1;
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] < medium) {
                    newArray[l] = nums[i];
                    l -= 2;
                } else if (nums[i] > medium) {
                    newArray[r] = nums[i];
                    r += 2;
                }
            }
        } else {
            int i = 0;
            int j = size - 2;
            for (int runner = 0; runner < size; runner++) {
                if (nums[runner] < medium) {
                    newArray[i] = nums[runner];
                    i += 2;
                } else if (nums[runner] > medium) {
                    newArray[j] = nums[runner];
                    j -= 2;
                }
            }
        }

        for (int i = 0; i < size; i++) {
            nums[i] = newArray[i];
        }
    }

    private int medium(int[] nums) {
        int size = nums.length;
        return kTh(nums, size / 2);
    }

    private int kTh(int[] nums, int k) {
        int start = 0;
        int end = nums.length - 1;

        while (start < end) {
            int partition = partition(nums, start, end);
            if (partition == k) {
                return nums[partition];
            } else if (partition < k) {
                start = partition + 1;
            } else {
                end = partition - 1;
            }
        }

        return nums[k];
    }

    private int partition(int[] nums, int start, int end) {
        if (start == end) return start;

        int pivot = nums[start];
        int i = start + 1;
        int j = end;

        while (true) {
            while (i <= end && nums[i] <= pivot) {
                i++;
            }

            while (j >= start + 1 && nums[j] > pivot) {
                j--;
            }

            if (i > j) {
                break;
            }

            swap(nums, i, j);
        }

        swap(nums, start, j);
        return j;
    }

    private void swap(int[] nums, int start, int end) {
        if (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
        }
    }


}

results matching ""

    No results matching ""