当前位置: 首页 > ai >正文

Swift 解 LeetCode 324:一步步实现摆动排序 II,掌握数组重排的节奏感

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码(Swift)
    • 题解代码分析
      • 步骤一:排序数组
      • 步骤二:左右指针分段
      • 步骤三:按位置交错插入
    • 示例测试及结果
      • 示例 1
      • 示例 2
      • 示例 3(边界情况)
    • 时间复杂度分析
    • 空间复杂度分析
    • 总结

摘要

摆动排序听起来像在跳舞,实际上它确实是让数组的数字“上下起伏”。我们要把一个整数数组重新排列,满足 nums[0] < nums[1] > nums[2] < nums[3]... 这种交错顺序。这篇文章会用 Swift 带你从头撸清楚摆动排序背后的技巧,包括排序、分组、巧妙插入的实战过程。

描述

题目要求我们把一个数组 nums 改造成如下的交错结构:

nums[0] < nums[1] > nums[2] < nums[3] ...

这个结构的关键点是:

  • 奇数下标元素大于相邻的偶数下标元素。
  • 偶数下标元素小于相邻的奇数下标元素。

可以认为是局部波峰波谷结构:小、大、小、大……

你不需要返回新的数组,而是直接修改原数组即可。

题解答案

我们可以先对数组排序,然后将较小的数填在偶数位,较大的数填在奇数位。

这个策略保证了交错关系。重点是我们要“倒着”填充数组,避免相邻重复值打破摆动规则。

题解代码(Swift)

func wiggleSort(_ nums: inout [Int]) {let sorted = nums.sorted()let n = nums.countvar left = (n - 1) / 2var right = n - 1for i in 0..<n {if i % 2 == 0 {nums[i] = sorted[left]left -= 1} else {nums[i] = sorted[right]right -= 1}}
}

题解代码分析

步骤一:排序数组

let sorted = nums.sorted()

我们先排序一遍数组,这样方便从中间拆成两个部分。

步骤二:左右指针分段

var left = (n - 1) / 2  // 前半部分的最大索引(用于偶数位)
var right = n - 1       // 后半部分的最大索引(用于奇数位)

这个拆法保证了我们从中间往前、往后取值,不会让重复数字挤在一起。

步骤三:按位置交错插入

for i in 0..<n {if i % 2 == 0 {nums[i] = sorted[left]left -= 1} else {nums[i] = sorted[right]right -= 1}
}
  • 偶数位:从左半部分最大往前取(最小值)
  • 奇数位:从右半部分最大往前取(最大值)

最终形成“小大小大”这样的节奏排序。

示例测试及结果

示例 1

var nums1 = [1, 5, 1, 1, 6, 4]
wiggleSort(&nums1)
print(nums1)  // 输出如:[1,6,1,5,1,4] 或类似交错结构

示例 2

var nums2 = [1, 3, 2, 2, 3, 1]
wiggleSort(&nums2)
print(nums2)  // 输出如:[2,3,1,3,1,2]

示例 3(边界情况)

var nums3 = [1]
wiggleSort(&nums3)
print(nums3)  // 输出:[1]

时间复杂度分析

  • 排序:O(n log n)
  • 重排:O(n)
  • 总时间复杂度:O(n log n)

空间复杂度分析

  • 我们使用了一个额外的排序数组 sorted,空间为 O(n)
  • 总空间复杂度:O(n)(如果原地排序并三指针替换,可降到 O(1))

总结

“摆动排序”这题不只是让数字跳个舞,更是考验我们如何拆分数组、如何巧妙插入。

你需要掌握的几个重点:

  • 排序 + 分段思维
  • 左右指针从两端交替插入
  • 巧妙处理重复值,避免打破排序节奏
http://www.xdnf.cn/news/15089.html

相关文章:

  • 雷达遥感星座微波射频组件抗辐照MCU的选型与实践
  • 【JMeter】接口加密
  • 【JMeter】调试方法
  • 学弟让我帮忙写一个学生管理系统的后端,我直接上科技
  • [大模型问数]实现大模型调用MYSQL(03)【MCP笔记】
  • Webview 中可用的 VS Code 方法
  • Playwright Python 教程:网页自动化
  • 飞算JavaAI:新一代智能编码引擎,革新Java研发范式
  • Linux进程间通信--命名管道
  • 深度学习入门教程(三)- 线性代数教程
  • react打包发到线上报错Minified React error #130
  • 如何快速掌握WeNet:从零到一的端到端语音识别学习指南
  • spring-ai RAG(Retrieval-Augmented Generation)
  • 上位机知识篇---网络通信端口
  • 线程邮箱(线程间通信的异步缓存机制)
  • OBB旋转框检测配置与训练全流程(基于 DOTA8 数据集)
  • 云原生周刊:镜像兼容性
  • 十、MyBatis的逆向工程
  • 美颜SDK贴纸引擎设计指南:动画、识别与适配的实现逻辑
  • 华为数据通信网络基础
  • 香港站群服务器8C/4C/2C/1C有什么区别
  • 使用you-get命令下载视频/音频/图像
  • 北京-4年功能测试2年空窗-报培训班学测开-第四十八天
  • 【世纪龙科技】几何G6新能源汽车结构原理教学软件
  • 60 美元玩转 Li-Fi —— 开源 OpenVLC 平台入门(附 BeagleBone Black 驱动简单解析)
  • 飞算Java AI:专为 Java 开发者打造的智能开发引擎
  • uniapp制作一个个人页面
  • C++11堆操作深度解析:std::is_heap与std::is_heap_until原理解析与实践
  • [Reverse1] Tales of the Arrow
  • intellij idea的重命名shift+f6不生效(快捷键被微软输入法占用)