Medium草稿★★★★★O(n) 時間 · O(1) 空間
ArrayGreedySorting
Patterns🪙 貪心🔢 排序後處理
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

280Wiggle SortArrays & HashingMediumArrays & Hashing

給定未排序的陣列 nums,原地重排使得 nums[0] <= nums[1] >= nums[2] <= nums[3] ...(交替的小於等於和大於等於)。

Example:

Input: nums = [3,5,2,1,6,4] Output: [3,5,1,6,2,4](任何滿足 wiggle 條件的排列皆可)

Intuition

TIP

核心思路:一次遍歷,若 index 為奇數時 nums[i] < nums[i-1],或 index 為偶數時 nums[i] > nums[i-1],就交換相鄰兩元素。

Approaches

1. Sort Then Swap — O(n log n) / O(1)
  • Idea: 先排序,然後每兩個元素一組交換(swap nums[1]nums[2],swap nums[3]nums[4]…)
  • Time: O(n log n) - 排序主導
  • Space: O(1) - 原地排序後原地交換
class Solution {
    fun wiggleSort(nums: IntArray) {
        nums.sort()
        for (i in 1 until nums.size - 1 step 2) {
            val temp = nums[i]
            nums[i] = nums[i + 1]
            nums[i + 1] = temp
        }
    }
}
⭐ 2. One-Pass Greedy Swap — O(n) / O(1)
  • Idea: 遍歷陣列,根據當前 index 的奇偶性判斷是否需要交換相鄰元素
  • Time: O(n) - 一次遍歷
  • Space: O(1) - 原地操作
class Solution {
    fun wiggleSort(nums: IntArray) {
        for (i in 1 until nums.size) {
            if ((i % 2 == 1 && nums[i] < nums[i - 1]) ||
                (i % 2 == 0 && nums[i] > nums[i - 1])) {
                val temp = nums[i]
                nums[i] = nums[i - 1]
                nums[i - 1] = temp
            }
        }
    }
}

WARNING

為什麼交換不會破壞前面已建立的 wiggle 性質?以奇數位為例:若 nums[i] < nums[i-1],交換後 nums[i-1] 變更小,而偶數位 i-1 本就要求較小值,所以 i-2i-1 的關係不會被破壞。

🔑 Takeaways