# 324. Wiggle Sort II

标签(空格分隔): leetcode



1. 原题

Given an unsorted array nums, reorder it such that nums[0] < nums1 > 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?

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

2. 分析:

  • 只要输出一种满足以上需求的数组就可以
  • 排序之后, 只要按中位数分为2组,比如:[1,2,3,4,5,6,7,8] ==>
    [1,2,3,4], [5,6,7,8], 然后按照顺序组合[1, 5], [2, 6], [3, 7], [4, 8]。然后就可以得到满足的数组:[1,5,2,6,3,7,4,8]。当出现奇数长度的数组的时候, 比如原来的数组加上一个5, 那么就可以在最后补上5变成[1,5,2,6,3,7,4,8,5]
  • 找到中位数的下一位: A[(len - 1)/2 + 1]
    这一位到数组结尾都大于对称位的数

3. 需要注意的一些细节

  • 在第二点的分析中有一点错误, 就是需要从后往前填数,不能从前往后

    比如: [4,5,5,6]正确输出应该是[5,6,5,4]
    按照分析中的算法, 结果应该是[4,5] + [5,6] ==> [4,5,5,6]
    假设我们根据 len的奇偶和下标 i 的奇偶来判断,当 len 为偶数的时候, 先填大的部分,再填小的部分 [5, 6] + [4, 5] ==> [5, 4, 6, 5], 那么就不符合要求了。

  • 从后往前填, 在开始的时候,如果len是一个奇数, 需要先在后面填小的,这样中位数就会填在第一位, 中位数的下一位是大于他的数

4. 代码


void wiggleSort(vector<int>& nums) {
    vector<int> sorted(nums);
    sort(sorted.begin(), sorted.end());
    for (int i=nums.size()-1, j=0, k=i/2+1; i>=0; i--)
        nums[i] = sorted[i&1 ? k++ : j++];
}
<think> 我们已知用户当前的问题是关于Python内置的sort方法所使用的排序算法。根据之前提供的引用资料,我们并没有直接关于Python sort方法的具体算法描述,因此需要结合外部知识来回答。但根据已知的引用,我们可以参考一些排序算法的实现(如引用1、2、3中的wiggle sort、插入排序、计数排序),但注意这些并非Python sort使用的算法。 实际上,Python的sort方法使用的是Timsort算法,这是一种结合了归并排序和插入排序的混合排序算法,由Tim Peters于2002年设计并应用于Python。Timsort旨在处理现实世界中多种多样的数据情况,尤其擅长处理部分有序的数据集。 下面我将按照要求详细回答: </think> Python 的 `sort()` 方法采用 **Timsort 算法**,这是一种结合了归并排序(Merge Sort)和插入排序(Insertion Sort)优势的混合算法。以下是其核心原理和特点: --- ### Timsort 的核心设计 1. **自适应分段** 扫描数组,将连续升序/降序片段识别为「自然有序段」(run),降序段会被反转优化。例如: `[5, 9, 12, 3, 7, 15]` → 分段为 `[5,9,12]` 和 `[3,7,15]` 2. **插入排序优化小片段** 当片段长度 $min\_run < 64$ 时(经验值),使用插入排序处理。插入排序在小数据量时效率极高(时间复杂度 $O(n^2)$ 但常数项极小)[^2]。 3. **归并排序合并片段** 通过归并排序的 **平衡合并策略** 逐步合并片段: - 使用栈管理待合并片段 - 合并时保证栈顶三个片段满足: $$|Z| > |Y| + |X|$$ $$|Y| > |X|$$ 确保合并操作复杂度均衡(避免最坏情况) --- ### 性能优势 | 场景 | 时间复杂度 | 说明 | |--------------|-------------|--------------------------| | 最佳情况 | $O(n)$ | 完全有序数组 | | 平均情况 | $O(n \log n)$ | 随机数据 | | 最坏情况 | $O(n \log n)$ | 严格保证(优于快速排序) | | 空间复杂度 | $O(n)$ | 归并操作需要临时空间 | **关键优势**: - 对部分有序数据效率接近 $O(n)$ - 稳定排序(相等元素顺序不变) - 规避归并排序和快速排序的最坏情况 --- ### 示例演示 ```python data = [3, 1, 4, 1, 5, 9, 2, 6] data.sort() # 调用Timsort print(data) # 输出: [1, 1, 2, 3, 4, 5, 6, 9] ``` --- ### 设计哲学 Timsort 的核心思想源自 **现实数据通常部分有序** 的观察。通过利用数据的现有有序性,减少不必要的比较操作。其合并策略灵感源自 **平衡二叉树** ,确保合并树的深度最小化[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值