Medium草稿★★★★★O(n log n) 時間 · O(1) 空間
Sliding WindowSortingGreedyBinary Search
Patterns🪟 滑動視窗🎯 二分搜尋🪙 貪心🔢 排序後處理
尚未複習過

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

1838Frequency of The Most Frequent ElementSliding WindowMediumSliding Window

給定整數陣列 nums 和整數 k,可以對任一元素加 1(最多操作 k 次),回傳操作後陣列中最高頻率的元素的頻率。

Example:

Input: nums = [1,2,4], k = 5 Output: 3(把 1 加到 4 需 3 次,把 2 加到 4 需 2 次,共 5 次,全部變成 4)

Intuition

TIP

核心思路:排序後用滑動視窗,嘗試把視窗內所有元素都提升到視窗最右邊的值,所需操作次數 = nums[right] * windowSize - windowSum,若 <= k 則合法。

Approaches

1. Sort + Binary Search — O(n log n) / O(n)
  • Idea: 排序後,對每個 right,用二分搜尋找到最左的 left,使得操作次數 <= k
  • Time: O(n log n) - 排序 + 二分
  • Space: O(n) - prefix sum
class Solution {
    fun maxFrequency(nums: IntArray, k: Int): Int {
        nums.sort()
        val prefix = LongArray(nums.size + 1)
        for (i in nums.indices) prefix[i + 1] = prefix[i] + nums[i]

        var result = 1
        for (right in nums.indices) {
            var lo = 0
            var hi = right
            while (lo < hi) {
                val mid = (lo + hi) / 2
                val windowSize = right - mid + 1
                val cost = nums[right].toLong() * windowSize - (prefix[right + 1] - prefix[mid])
                if (cost <= k) hi = mid else lo = mid + 1
            }
            result = maxOf(result, right - lo + 1)
        }
        return result
    }
}
⭐ 2. Sort + Sliding Window — O(n log n) / O(1)
  • Idea: 排序後,用可變大小滑動視窗,維護視窗總和;當操作成本超過 k 時收縮左邊界
  • Time: O(n log n) - 排序主導,滑動視窗 O(n)
  • Space: O(1) - 原地排序
class Solution {
    fun maxFrequency(nums: IntArray, k: Int): Int {
        nums.sort()
        var left = 0
        var windowSum = 0L
        var result = 1

        for (right in nums.indices) {
            windowSum += nums[right]
            // 當前視窗要全部變成 nums[right] 的成本
            while (nums[right].toLong() * (right - left + 1) - windowSum > k) {
                windowSum -= nums[left]
                left++
            }
            result = maxOf(result, right - left + 1)
        }
        return result
    }
}

WARNING

計算成本時要用 Long,因為 nums[right] * windowSize 可能溢位 Int。

🔑 Takeaways