leecode 解题总结:324. Wiggle Sort II

来源:互联网 发布:有淘宝卖家手机版本 编辑:程序博客网 时间:2024/06/15 09:15
#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 461 3 2 2 3 1输出:1 4 1 5 1 61 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 64 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=2int 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;}

0 0