【问题标题】:Why is a sliding window algorithm considered O(n) and not O(n^2)?为什么滑动窗口算法被认为是 O(n) 而不是 O(n^2)?
【发布时间】:2022-01-02 03:26:28
【问题描述】:

关于 leetcode 424. Longest Repeating Character Replacement - (https://leetcode.com/problems/longest-repeating-character-replacement)

给你一个字符串 s 和一个整数 k。你可以选择任何 字符串的字符并将其更改为任何其他大写英文 特点。您最多可以执行此操作 k 次。

返回包含相同字母的最长子串的长度 执行上述操作后即可得到。

这是我的解决方案:

func characterReplacement(s string, k int) int {
    
    var out int
    for i, _ := range s {
        c := make(map[byte]int)
        count := 0
        
        for j:= i; j < len(s); j++ {
            count +=1
            c[s[j]] += 1
            
            
            // determine max freq
            maxFreq := 0
            for _, v := range c {
                if v > maxFreq {
                    maxFreq = v
                }
            }
            
            if count - maxFreq <= k {
                if count > out {
                    out = count
                }
            }
        }
    }
    return out
}

排除determine max freq循环,这种类型的滑动窗口算法被认为是O(n),但我不明白为什么,对我来说应该是O(n^2)。

谁能帮我理解为什么时间复杂度是 O(n) 而不是 O(n^2)?

【问题讨论】:

  • 你是那个声称它是 O(n) 的人,所以你告诉我们。
  • 一般来说,如果窗口以某种“智能”方式滑动,使得算法为 O(n),那么我们称之为“滑动窗口”算法;如果考虑了所有可能的窗口并且算法是 Ө(n²),那么我们将其称为“蛮力”算法;-) 但请注意,“滑动窗口”有点模糊和模棱两可,并且已用于完全不同类型的算法。

标签: algorithm go time-complexity sliding-window


【解决方案1】:

你实现算法的方式,复杂度是 O(n^2)。如果你声称“这种算法被认为是 O(n)”,那么你没有正确实现这个算法。

这是这个问题的 O(n) 解决方案,用 JavaScript (source) 编写:

var characterReplacement = function(s, k) {
    // Keep count of all the characters in the string
    const chars = {}
    // left pointer, character with the current max frequency, return value
    let left = 0, maxf = 0, output = 0
    for(let right = 0; right < s.length; right++) {
        const char = s[right]
        // Increment count of the current character
        chars[char] = 1 + (chars[char] || 0)
        // Update the character frequency
        maxf = Math.max(maxf, chars[char])
        // Shrink the window of characters we are looking at until we can have a window of all the same characters + k charcters to change
        while((right-left+1) - maxf > k) {
                chars[s[left]] -= 1
                left++
          }
        // Update the output if the current window is greater than our previous max window
        output = Math.max(output, right - left +1)
    }
    return output
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多