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

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

179Largest NumberArrays & HashingMediumArrays & Hashing

給定一組非負整數 nums,將它們排列成最大的數字並回傳字串。結果可能很大,回傳字串而非數字。

Example:

Input: nums = [10, 2] Output: “210”

Intuition

TIP

核心思路:自定義排序——比較兩個數 ab 時,比較 "ab""ba" 的字串大小,較大的排前面。

Approaches

1. Custom Comparator Sort — O(n log n * k) / O(n * k)
  • Idea: 將數字轉字串,用自定義比較器排序,最後拼接
  • Time: O(n log n * k) - 排序 O(n log n),每次比較涉及字串拼接 O(k),k 為平均數字位數
  • Space: O(n * k) - 字串陣列
class Solution {
    fun largestNumber(nums: IntArray): String {
        val strs = nums.map { it.toString() }
            .sortedWith { a, b -> (b + a).compareTo(a + b) }

        if (strs[0] == "0") return "0"  // 全是 0 的情況

        return strs.joinToString("")
    }
}
⭐ 2. Custom Comparator (array sort, in-place) — O(n log n * k) / O(n * k)
  • Idea: 同上邏輯但用陣列排序避免額外集合開銷,並用 StringBuilder 拼接
  • Time: O(n log n * k) - 排序主導
  • Space: O(n * k) - 字串陣列
class Solution {
    fun largestNumber(nums: IntArray): String {
        val strs = Array(nums.size) { nums[it].toString() }

        strs.sortWith(Comparator { a, b ->
            (b + a).compareTo(a + b)
        })

        if (strs[0] == "0") return "0"

        val sb = StringBuilder()
        for (s in strs) sb.append(s)
        return sb.toString()
    }
}

WARNING

邊界情況:當所有數字都是 0 時(如 [0, 0]),排序後第一個元素是 “0”,結果應該回傳 “0” 而不是 “00”。

🔑 Takeaways