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

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

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次操作。

返回在执行上述操作后,包含相同字母的最长子字符串的长度。

以下是我的解决方案:

  1. func characterReplacement(s string, k int) int {
  2. var out int
  3. for i, _ := range s {
  4. c := make(map[byte]int)
  5. count := 0
  6. for j:= i; j < len(s); j++ {
  7. count +=1
  8. c[s[j]] += 1
  9. // determine max freq
  10. maxFreq := 0
  11. for _, v := range c {
  12. if v > maxFreq {
  13. maxFreq = v
  14. }
  15. }
  16. if count - maxFreq <= k {
  17. if count > out {
  18. out = count
  19. }
  20. }
  21. }
  22. }
  23. return out
  24. }

除去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:

  1. func characterReplacement(s string, k int) int {
  2. var out int
  3. for i, _ := range s {
  4. c := make(map[byte]int)
  5. count := 0
  6. for j:= i; j &lt; len(s); j++ {
  7. count +=1
  8. c
    展开收缩
    ] += 1
  9. // determine max freq
  10. maxFreq := 0
  11. for _, v := range c {
  12. if v &gt; maxFreq {
  13. maxFreq = v
  14. }
  15. }
  16. if count - maxFreq &lt;= k {
  17. if count &gt; out {
  18. out = count
  19. }
  20. }
  21. }
  22. }
  23. return out
  24. }

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编写(来源):

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

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):

  1. var characterReplacement = function(s, k) {
  2. // Keep count of all the characters in the string
  3. const chars = {}
  4. // left pointer, character with the current max frequency, return value
  5. let left = 0, maxf = 0, output = 0
  6. for(let right = 0; right &lt; s.length; right++) {
  7. const char = s[right]
  8. // Increment count of the current character
  9. chars[char] = 1 + (chars[char] || 0)
  10. // Update the character frequency
  11. maxf = Math.max(maxf, chars[char])
  12. // Shrink the window of characters we are looking at until we can have a window of all the same characters + k charcters to change
  13. while((right-left+1) - maxf &gt; k) {
  14. chars[s[left]] -= 1
  15. left++
  16. }
  17. // Update the output if the current window is greater than our previous max window
  18. output = Math.max(output, right - left +1)
  19. }
  20. return output
  21. };

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:

确定