#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
/*
问题:
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?
分析:给定一个为排序的数组,使其排序的形式如下:nums[0] < nums[1] > nums[2] < nums[3]
分析发现:这是一种波形的排序,中间大于两边,即: 小,大,小,大,小
如果有奇数个元素,则n/2 + 1个元素在下面,n/2个元素在上面。
如果有偶数个元素,则n/2个元素在下面,n/2个元素在上面
如果不考虑空间和时间,先从数组中挑选出n/2个最小的元素,每次挑选一个最小的元素,然后
挑选剩余元素中任意元素,重复上述操作,直至结束。
那么如何挑选最小的一半元素,可以先排序,然后进行上述操作
题目要求尽量在O(n)时间完成,并且使用原地排序。
最简单的方法:
输入:
6(数组元素个数)
1 5 1 1 6 4
6
1 3 2 2 3 1
输出:
1 4 1 5 1 6
1 2 1 3 2 3
报错:
Input:
[4,5,5,6]
Output:
[4,5,5,6]
Expected:
[5,6,4,5]
关键:
1 如果不考虑空间和时间,先排序。从数组中挑选出n/2个最小的元素,每次从最小数组中挑选一个最大的元素,然后
挑选最大数组中最大元素放入结果集,重复上述操作,直至结束。
2 摆放的时候要把较小数组中最大的元素优先放在前面,把较大数组中最大的放在前面
才能避免出现重复元素的时候不是波形。
我把较小元素从小到达排列,把较大元素从小到大排列,可能导致不是波形的排序
例如整个数组:4 5 5 6,较小数组是:4 5,较大数组为:5 6
4 5 5造成不符合要求,5 6 4符合
3参考解法:http://blog.csdn.net/qingyuanluofeng/article/details/58666552
采用三路划分+中位数方式。
通过将下标(2*i + 1) % (len|1)的方式可以构成1 3 5 0 2 4 这种下标,这种下标
刚好是奇数下标为较大数,偶数下标为较小数。
采用三路划分,将大于中位数的放在前面,中位数位置不变,小于中位数的放在后面
再加上下标映射,就可以组成
4
//获取中位数
auto mPtr = nums.begin() + size / 2;//推导类型
nth_element(nums.begin() , mPtr , nums.end());
*/
class Solution {
public:
//进行下标映射
int getIndex(int i , int len)
{
return (2*i + 1) % (len | 1);//注意这里是取余
}
void wiggleSort(vector<int>& nums) {
if(nums.empty())
{
return;
}
int size = nums.size();
//获取中位数
auto mPtr = nums.begin() + size / 2;//推导类型
nth_element(nums.begin() , mPtr , nums.end());
int mid = *mPtr;
int low = 0;
int high = size - 1;
int i = 0;
//以中位数进行三路划分
while(i <= high)
{
//大于中位数,交换到最左边
if(nums[ getIndex(i , size)] > mid)
{
swap( nums[getIndex(i++ , size)] , nums[getIndex(low++ , size)] );
}
//小于中位数,交换到最右边
else if( nums[ getIndex(i , size) ] < mid )
{
swap( nums[getIndex(i ,size)] , nums[ getIndex(high--, size) ] );//注意当前位置不需要前进
}
//遇到中位数
else
{
i++;
}
}
}
void wiggleSort2(vector<int>& nums) {
if(nums.empty())
{
return;
}
sort(nums.begin() , nums.end());
int size = nums.size();
vector<int> result;
int minBegin = 0;//
int minEnd = (size+1)/2 - 1;
int maxBegin = (size+1)/2;// (3+1)/2= 2 , (4+1)/2=2
int maxEnd = size - 1;
while(minBegin <= minEnd || maxBegin <= maxEnd)
{
if(minBegin <= minEnd)
{
result.push_back(nums.at(minEnd--));//较小数组按从大到小排列
}
if(maxBegin <= maxEnd)
{
result.push_back(nums.at(maxEnd--));//较大数组按从大到小牌类
}
}
swap(nums , result);
}
};
void print(vector<int>& result)
{
if(result.empty())
{
cout << "no result" << endl;
return;
}
int size = result.size();
for(int i = 0 ; i < size ; i++)
{
cout << result.at(i) << " " ;
}
cout << endl;
}
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
vector<int> result;
while(cin >> num )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
solution.wiggleSort(nums);
print(nums);
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}
leecode 解题总结:324. Wiggle Sort II
最新推荐文章于 2021-12-06 20:38:16 发布