【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

Wiggle Sort II
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?


C++

//问题:摆动排序,a[0] < a[1] > a[2] < a[3]...
//??没看懂,以后再看
//方法二:利用快排中一步(nth_element函数)将序列分成两段,以中值为枢轴,从各段段首(或段尾)开始选数
//思路解析:假设排序后为a1 a2...an mid b1 b2...bn,则组织为a1 b1 a2 b2...
//此法时间复杂度为O(n),如果没有O(1)的空间复杂度,比较简单,正是这个限制增加了复杂度
class Solution {
public:
    void wiggleSort(vector<int>& nums) {
        int m = nums.size();
        auto mptr = nums.begin() + (m-1)/2;
        nth_element(nums.begin(), mptr, nums.end());
        int median = *mptr;
        int i = 1;   // position for the larger values: start with first odd index
        int j = ((m - 1) & 1) ? m - 2 : m - 1;  // position for the smaller values: start with last even index
        for (int l = 0; l < m; ++l) {
            if (nums[l] > median) {  // fill the large element
                if (l <= i && (l & 1)) continue;       // skip the elements which are  already checked: 1, 3, 5, ..., i
                swap(nums[l--], nums[i]);
                i += 2;
            } else if (nums[l] < median) {  // fill the smaller element
                if (l >= j && (l & 1) == 0) continue;     // skip the elements whcih are checked: j, j + 2, ..., lastEvenIndex
                swap(nums[l--], nums[j]);
                j -= 2;
            }
       }
    }
};
//方法一:排序后,分成两段,从各段末尾依次取数(可以避免相等数弄在一起)
//不过此法的时间复杂度为O(nlogn),空间复杂度为O(n),不满足题意
//思路解析:假设排序后为a1 a2...an b1 b2...bn,则组织为an bn an-1 bn-1...
class Solution
{
public:
    void wiggleSort(vector<int>& a)
    {
        int n = a.size();
        sort(a.begin(),a.end());
        if(n<=2) return; //小于两个元素时,直接退出
      
        vector<int> temp = a; 
        int i = 0, j=(n-1)/2, k=n-1; //i用来遍历a, j用来遍历temp第一段(从末尾开始),k用来遍历第二段。
        for(i = 0; i < n; i++)
        {
            a[i] = (i&1)? temp[k--]:temp[j--];//如果i为奇数,取第二段的数(较大),如果为偶数,取第一段的数(较小)
            //注:当n为奇数时,两段长度不等,第一段比第二段多1,但是上述等式可以保证最后一个数a[n-1]选择temp[0]
        }
    }
};
/*
//摆动排序,a[0] < a[1] > a[2] < a[3]...
//要得到O(n)时间复杂度,O(1)空间复杂度,可以借鉴wiggle sort I(a[0] <= a[1] >= a[2] <= a[3]...)中的思路
//i为奇数时,a[i]>a[i-1], 偶数时,a[i]<a[i-1], 根据这一规律,遍历整个序列,不符合则交换
//测试结果表明,对于序列中有多个连续相等数时,此方法不行,因为按照交换策略,相等的数会交换,但是交换后并不会满足
//i为奇数时,a[i]>a[i-1], 偶数时,a[i]<a[i-1]的规律,而是仍然相等。
class Solution
{
public:
    void wiggleSort(vector<int>& a)
    {
        int n = a.size();
        if(n <= 1) return; //元素个数少于1个时,退出
       
        for(int i = 1; i < n; i++)
        {
            if((i%2 == 1 && a[i]<=a[i-1]) || (i%2 == 0 && a[i]>=a[i-1]))
            {
                swap(a[i], a[i-1]);//如果不符合摆动规律则交换
            }
        }
    }
};
*/

Wiggle Sort I
Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3]....
For example, given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4].
 
这道题让我们求摆动排序,跟Wiggle Sort II相比起来,这道题的条件宽松很多,只因为多了一个等号。由于等号的存在,当数组中有重复数字存在的情况时,也很容易满足题目的要求。这道题我们先来看一种时间复杂度为O(nlgn)的方法,思路是先给数组排个序,然后我们只要每次把第三个数和第二个数调换个位置,第五个数和第四个数调换个位置,以此类推直至数组末尾,这样我们就能完成摆动排序了,参见代码如下:
//解法一:
// Time Complexity O(nlgn)
class Solution {
public:
    void wiggleSort(vector<int> &nums) {
        sort(nums.begin(), nums.end());
        if (nums.size() <= 2) return;
        for (int i = 2; i < nums.size(); i += 2) {
            swap(nums[i], nums[i - 1]);
        }
    }
};

这道题还有一种O(n)的解法,根据题目要求的nums[0] <= nums[1] >= nums[2] <= nums[3]....,我们可以总结出如下规律:
当i为奇数时,nums[i] >= nums[i - 1]
当i为偶数时,nums[i] <= nums[i - 1]
那么我们只要对每个数字,根据其奇偶性,跟其对应的条件比较,如果不符合就和前面的数交换位置即可,参见代码如下:
//解法二:
// Time Complexity O(n)
class Solution {
public:
    void wiggleSort(vector<int> &nums) {
        if (nums.size() <= 1) return;
        for (int i = 1; i < nums.size(); ++i) {
            if ((i % 2 == 1 && nums[i] < nums[i - 1]) || (i % 2 == 0 && nums[i] > nums[i - 1])) {
                swap(nums[i], nums[i - 1]);
            }
        }
    }
};

来源:http://www.cnblogs.com/grandyang/p/5177285.html

转载于:https://www.cnblogs.com/wikiwen/p/10225971.html

【LeetCode 剑指offer刷题】查找与排序题14:Wiggle Sort(系列)相关推荐

  1. 【LeetCode 剑指offer刷题】矩阵题1:4 有序矩阵中的查找( 74. Search a 2D Matrix )(系列)...

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 74. Search a 2D Matrix Write an efficient algorithm that s ...

  2. 【LeetCode 剑指offer刷题】查找与排序题12:Top K Frequent Elements

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) Top K Frequent Elements Given a non-empty array of integer ...

  3. 【LeetCode 剑指offer刷题】数组题2:57 有序数组中和为s的两个数(167 Two Sum II - Input array is sorted)...

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 57 有序数组中和为s的两个数 题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是 ...

  4. 【LeetCode 剑指offer刷题】树题16:Kth Smallest Element in a BST

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) Kth Smallest Element in a BST Given a binary search tree, ...

  5. 【LeetCode 剑指offer刷题】树题19:8 二叉树中序遍历的下一个结点

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 8 二叉树中序遍历的下一个结点 题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注 ...

  6. 【LeetCode 剑指offer刷题】树题6:28 对称二叉树(101. Symmetric Tree)

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 101. Symmetric Tree /**  * Definition for a binary tree no ...

  7. 【LeetCode 剑指offer刷题】字符串题6:67 把字符串转成整数

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) 67 把字符串转成整数 题目描述 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符 ...

  8. 【LeetCode 剑指offer刷题】回溯法与暴力枚举法题6:Number of Islands

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) Number of Islands Given a 2d grid map of '1's (land) and ' ...

  9. 【LeetCode 剑指offer刷题】字符串题12:Valid Palindrome(回文词系列)

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) Valid Palindrome Given a string, determine if it is a pali ...

最新文章

  1. 2W+好评,这个python数据分析课程免费开放3天!
  2. WindowsPhone7入手,实在的照片
  3. 关于ewebeditor行距
  4. 模拟教务评教(强智教务)—一件评教实现原理
  5. Buuctf(misc) 后门查杀
  6. 2020年第十一届蓝桥杯 - 省赛 - C/C++大学生A组 - C.蛇形填数
  7. SQL Server 将一个表中字段的值复制到另一个表的字段中
  8. 为什么openstack要用rabbitmq这类消息中间件来进行RPC这类的操作呢,直接rpc不行吗?
  9. 目录:关于【稳定性建设之道】大纲速览
  10. opencv图像-拼接线的处理
  11. k邻近算法(KNN)实例
  12. C++ 优先级队列(priority_queue)
  13. java String 常用方法集合
  14. python怎么在运行中查看执行状态_python,_python程序运行时 查看对象状态,python - phpStudy...
  15. PHP 100以内质数表
  16. 敏捷-年金、净现值NPV、IRR、现值PV、终值FV、EAR概念与案例(转)
  17. Linux-ubuntu系统查看显卡型号、显卡信息详解、显卡天梯图
  18. 以太网未识别的网络问题
  19. 企业邮箱是什么及与个人邮箱的区别
  20. 车主因眼睛小被自动驾驶误判?——智能座舱CV体验的经典corner case剖析 by 资深AI产品经理@方舟...

热门文章

  1. 开放下载!《Rocket MQ 使用排查指南》精解100+常见问题
  2. 官方剧透:1.11 发版前我们偷看了 Flink 中文社区发起人的聊天记录
  3. 什么是人机对话模型?阿里小蜜团队写了1.5万字
  4. linux查看java运行日志,Linux下查看日志用到的经常使用命令
  5. 行波iq调制器_低功率IQ调制器的基带设计实例—电路精选(1)
  6. 《盗墓笔记》使用的这套技术,让美术可以在场景中任意使用灯光
  7. 如何用Unity和Cardboard做一款VR游戏
  8. 《守墓人》主程:如何用像素风做出真实的游戏世界
  9. 一劳永逸:域名支持通配符,ASP.NET Core中配置CORS
  10. idea配置tomcat必坑指南