Why is a sliding window algorithm considered O(n) and not O(n^2)?

huangapple go评论75阅读模式
英文:

Why is a sliding window algorithm considered O(n) and not O(n^2)?

问题

在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),在我看来应该是O(n^2)。

有人可以帮我理解为什么时间复杂度是O(n)而不是O(n^2)吗?

英文:

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

> You are given a string s and an integer k. You can choose any
> character of the string and change it to any other uppercase English
> character. You can perform this operation at most k times.
>
> Return the length of the longest substring containing the same letter
> you can get after performing the above operations.

Here's my solution:

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 &lt; len(s); j++ {
            count +=1
            c
展开收缩
] += 1 // determine max freq maxFreq := 0 for _, v := range c { if v &gt; maxFreq { maxFreq = v } } if count - maxFreq &lt;= k { if count &gt; out { out = count } } } } return out }

Excluding the determine max freq loop, this type of sliding window algorithm is considered O(n), but I can't see why that is, to me it should be O(n^2).

Can someone help me understand why the time complexity is O(n) and not O(n^2)?

答案1

得分: 3

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

这是一个O(n)的解决方案,用JavaScript编写(来源):

var characterReplacement = function(s, k) {
    // 保持对字符串中所有字符的计数
    const chars = {}
    // 左指针,当前最大频率的字符,返回值
    let left = 0, maxf = 0, output = 0
    for(let right = 0; right < s.length; right++) {
        const char = s[right]
        // 增加当前字符的计数
        chars[char] = 1 + (chars[char] || 0)
        // 更新字符频率
        maxf = Math.max(maxf, chars[char])
        // 缩小我们正在查看的字符窗口,直到我们可以有一个窗口,其中所有字符都相同+ k个要更改的字符
        while((right-left+1) - maxf > k) {
                chars[s[left]] -= 1
                left++
          }
        // 如果当前窗口大于我们先前的最大窗口,则更新输出
        output = Math.max(output, right - left +1)
    }
    return output
};
英文:

The way you implemented the algorithm, the complexity is O(n^2). If you claim that "this type of algorithm is considered O(n)", then you didn't correctly implement this algorithm.

Here is a O(n) solution for this problem, written in 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 &lt; 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 &gt; 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
};

huangapple
  • 本文由 发表于 2022年1月2日 11:26:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/70553416.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定