题目难度: 中等

原题链接

今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~

题目描述

在一个整数数组中,“峰”是大于或等于相邻整数的元素,相应地,“谷”是小于或等于相邻整数的元素。例如,在数组{5, 8, 4, 2, 3, 4, 6}中,{8, 6}是峰, {5, 2}是谷。现在给定一个整数数组,将该数组按峰与谷的交替顺序排序。

示例:

  • 输入: [5, 3, 1, 2, 3]
  • 输出: [5, 1, 3, 2, 3]

提示:

  • nums.length <= 10000

题目思考

  1. 如何利用已经排好序的部分?

解决方案

思路

  • 分析题目, 不难发现偶数下标需要是峰, 而奇数下标需要是谷
  • 这里我们可以使用贪心的做法, 从前向后遍历整个数组, 判断当前遍历的数字是否满足要求, 不满足时将其与后面满足要求的数字进行交换, 从而不影响已经排序好的部分
  • 既然前面的数字已经排好序了, 这里我们只需要比较当前数字和后一位数字即可, 如果当前数字不满足要求, 那么后一位数字一定满足要求, 将他们交换然后继续向后遍历, 最终即可得到整体排序的数组
  • 具体证明如下:
  1. 假如当前下标 i 需要是峰(偶数下标), 且前面的 0~i-1 都满足要求, 那么 i-1 是谷, nums[i]>=nums[i-1]

    1. 此时如果 nums[i]>=nums[i+1], 则 i 是满足要求的峰
    2. 而如果 nums[i]<nums[i+1], 那么 nums[i+1]>nums[i]>=nums[i-1], 即 nums[i+1]是满足要求的峰, 交换 nums[i]与 nums[i+1]即可
  2. 假如当前下标 i 需要是谷(奇数下标), 且前面的 0~i-1 都满足要求, 那么 i-1 是峰, nums[i]<=nums[i-1]
    1. 此时如果 nums[i]<=nums[i+1], 则 i 是满足要求的谷
    2. 而如果 nums[i]>nums[i+1], 那么 nums[i+1]<nums[i]<=nums[i-1], 即 nums[i+1]是满足要求的谷, 交换 nums[i]与 nums[i+1]即可
  • 下面的代码就对应了上面的整个过程, 并且有详细的注释, 方便大家理解

复杂度

  • 时间复杂度 O(N): 只需要遍历整个数组一遍
  • 空间复杂度 O(1): 只使用了几个常数空间的变量

代码

class Solution:def wiggleSort(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""# 贪心+偶峰奇谷+不满足时交换# 一次遍历, 若当前下标数字不满足要求, 则与后一位数字交换继续向后遍历, 不会影响之前已经排序好的峰谷for i in range(len(nums) - 1):# 偶数下标时需要是峰, peek是Truepeek = i & 1 == 0if peek and nums[i] < nums[i + 1] or not peek and nums[i] > nums[i + 1]:# 如果当前下标不满足要求, 则与下一个数字交换即可nums[i], nums[i + 1] = nums[i + 1], nums[i]

大家可以在下面这些地方找到我~

程序员面试金典 - 面试题 10.11. 峰与谷相关推荐

  1. 程序员面试金典 - 面试题 10.11. 峰与谷(排序/不排序)

    1. 题目 在一个整数数组中,"峰"是大于或等于相邻整数的元素,相应地,"谷"是小于或等于相邻整数的元素. 例如,在数组{5, 8, 2, 6, 3, 4, 3 ...

  2. 程序员面试金典 - 面试题 10.03. 搜索旋转数组

    题目难度: 中等 原题链接 今天继续更新程序员面试金典系列, 大家在公众号 算法精选 里回复 面试金典 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 搜索旋转数组.给定一个排序后的数组 ...

  3. [Leetcode][程序员面试金典][面试题16.11][JAVA][跳水板][数学][动态规划]

    [问题描述][简单] [解答思路] 边界问题 k=0 ,不能产生跳水板,返回空数组 shorter 等于longer,只有一种跳水板,返回longerk 思路 一般情况,k块木板,k种可能 跳水板的长 ...

  4. 程序员面试金典 - 面试题 10.03. 搜索旋转数组(二分查找)

    1. 题目 搜索旋转数组.给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详. 请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的.若有多个相同元素,返回索引值最小 ...

  5. 程序员面试金典 - 面试题 08.11. 硬币(背包DP)

    文章目录 1. 题目 2. 解题 1. 题目 硬币.给定数量不限的硬币,币值为25分.10分.5分和1分,编写代码计算 n 分有几种表示法.(结果可能会很大,你需要将结果模上1000000007) 示 ...

  6. 程序员面试金典 - 面试题 10.10. 数字流的秩(map/树状数组)

    文章目录 1. 题目 2. 解题 2.1 map 2.2 树状数组 1. 题目 假设你正在读取一串整数.每隔一段时间,你希望能找出数字 x 的秩(小于或等于 x 的值的个数). 请实现数据结构和算法来 ...

  7. 程序员面试金典 - 面试题 10.02. 变位词组(哈希map)

    1. 题目 编写一种方法,对字符串数组进行排序,将所有变位词组合在一起. 变位词是指字母相同,但排列不同的字符串. 示例: 输入: ["eat", "tea", ...

  8. 程序员面试金典 - 面试题 16.11. 跳水板(数学)

    1. 题目 你正在使用一堆木板建造跳水板. 有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer. 你必须正好使用 k 块木板.编写一个方法,生成跳水板所有可能的 ...

  9. 程序员面试金典 - 面试题 10.05. 稀疏数组搜索(二分查找)

    1. 题目 稀疏数组搜索.有个排好序的字符串数组,其中散布着一些空字符串,编写一种方法,找出给定字符串的位置. 示例1:输入: words = ["at", "" ...

最新文章

  1. Java Web(11) Spring MVC 返回Json
  2. webpack学习之路
  3. poj 1087 A Plug for UNIX 【最大流】
  4. C++ STL实现的优先队列( priority_queue )
  5. 任何傅里叶级数展开和卷积可以参考一下页面
  6. 201521123121 《Java程序设计》第14周学习总结
  7. python julian date_Python 的内嵌time模板翻译及说明
  8. \pset 、\x命令
  9. 小红书 “红”到翻车:你的骚操作闪了我的腰?
  10. Java类获取Spring容器的bean
  11. Kafka副本同步机制理解
  12. matlab的比较器模块,simulink中比较器
  13. win10新版蓝牙驱动没有电源管理问题
  14. 关于fftshift引发的问题与思考
  15. 【Spring笔记09】Spring中事务传播机制(注解方式)
  16. 瓴羊CEO朋新宇:从数据发现问题到数据创造价值|2022全球数字价值峰会-阿里云开发者社区
  17. ETW绕过PoC测试1--关闭你的ProcMon.exe
  18. 运行 python manage.py runserver
  19. 医学统计分析:心电图智能诊病
  20. Failed to load API definition

热门文章

  1. 【Weiler-Atherton算法】 计算机图形学多边形裁剪算法
  2. 密码学笔记5 非对称密钥算法
  3. 令人细思极恐的小故事_“&”号的令人惊讶的故事
  4. linux有没有类似于串口的,linux下类似Bus Hound的工具
  5. 【智能制造】当数据智能遇上工业制造
  6. 十三款著名跨平台游戏引擎(原文翻译部分转自游侠网)
  7. Python之旅.第十章.mysql.
  8. python写的hadoop实战_hadoop实战 pdf
  9. Git版本控制与github使用
  10. Springboot使用Specification连表查询LEFT