324. Wiggle Sort II
1. 题目描述
题目链接
Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3]…
Example 1:
Input: nums = [1, 5, 1, 1, 6, 4]
Output: One possible answer is [1, 4, 1, 5, 1, 6].
Example 2:
Input: nums = [1, 3, 2, 2, 3, 1]
Output: 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?
2. 题目分析
题目就一句话,给数组重排序,使得数组规律是奇数下标的关键字大于左右两边(偶数下标)的关键字。
3. 解决思路
一开始我想,先排序,然后将前半部分放到偶数下标,后半部分放到奇数下标不就OK了,为什么一开始就能知道先使用排序?因为我刷题是按标签分类刷题的,这题属于排序标签中,哈哈哈,我不确定如果没有标签提示,会不会立马想到先排序在移动关键字。
commit后,发现,只能通过部分事例,但有部分事例无法通过,如[4,5,5,6],使用我的思路,最后数组仍是[4,5,5,6],难道哪里不对?看看前辈的解决方案,发现换个思路,将前半段倒序填入偶数下标,将后半段倒序填入奇数下标。好气啊啊啊啊啊啊啊,换个顺序就能完美解决中间重复的问题。
即,整个算法步骤:
对数组排序,然后将前半部分倒序放到偶数下标,后半部分倒序放到奇数。时间复杂度O(nlogn),即用在排序算法中了,排序算法最优时间复杂度为O(nlogn),空间复杂度O(n)。网上看了下时间复杂度为O(n)的,有点复杂,太烧脑子了,后面有兴趣再看。
*4. 代码实现(java)
package com.algorithm.leetcode.sort;
import java.util.Arrays;
/**
* Created by 凌 on 2019/1/6.
* 描述:324. Wiggle Sort II
*/
public class WiggleSort {
public static void main(String[] args) {
// int[] nums = {1, 5, 1, 1, 6, 4};
int[] nums = {4, 5, 5, 6};
// int[] nums = {1, 3, 2, 2, 3, 1};
wiggleSort(nums);
for (int i = 0; i < nums.length; i++) {
System.out.printf(nums[i] + "\t");
}
System.out.println();
}
/**
* 对数组进行排序,然后将前半段倒序填入偶数下标,将后半段倒序填入奇数下标,
* 其原理是如果题目有解,则对于排好序的数组,间隔超过n/2的两个元素必不相等。
* 时间复杂度O(nlogn),空间复杂度O(n)。
* @param nums
*/
public static void wiggleSort(int[] nums) {
int[] sort = nums.clone();
Arrays.sort(sort);
int index = 0;
int count = (nums.length-1) / 2;
//将前半段倒序填入偶数下标
while (index < nums.length) {
nums[index] = sort[count];
index += 2;
count--;
}
count = nums.length-1;
index = 1;
//将后半段倒序填入奇数下标
while (index < nums.length) {
nums[index] = sort[count];
index += 2;
count--;
}
}
}