“Sliding window”的版本间的差异

来自wrc's Wiki
跳到导航 跳到搜索
(建立内容为“使用左右两个指针,按一定规则向右移动。注意 window 的大小并不一定是固定的。 == 使用 pattern == 在需要找一个区间的问…”的新页面)
 
 
第2行: 第2行:
  
 
== 使用 pattern ==
 
== 使用 pattern ==
 +
<ref>[http://www.noteanddata.com/leetcode-3-Longest-Substring-Without-Repeating-Characters-java-sliding-windows-solution-note.html#sliding-windows滑动窗口的特征和基本模版 sliding windows 滑动窗口的特征和基本模版]</ref> <ref>https://blog.csdn.net/fuxuemingzhu/article/details/82931106</ref>
  
在需要找一个区间的问题中,首先移动右指针使得满足要求,再移动左指针直到不满足要求,再移动右指针,持续如此,直到区间的右边界到达整体的结束点。
+
在需要找一个区间的问题中,
<ref>[http://www.noteanddata.com/leetcode-3-Longest-Substring-Without-Repeating-Characters-java-sliding-windows-solution-note.html#sliding-windows滑动窗口的特征和基本模版 sliding windows 滑动窗口的特征和基本模版]</ref> <ref>https://blog.csdn.net/fuxuemingzhu/article/details/82931106</ref>
 
  
 +
'''第一种情况:'''首先移动右指针使得满足要求,再移动左指针直到不满足要求,再移动右指针,持续如此,直到区间的右边界到达整体的结束点。
 
<syntaxhighlight lang=python>
 
<syntaxhighlight lang=python>
 
left = 0
 
left = 0
 +
init state
 
ret = worse case retval
 
ret = worse case retval
 
for right in range(n):
 
for right in range(n):
第17行: 第19行:
 
         left += 1
 
         left += 1
 
         update state
 
         update state
 +
return ret
 +
</syntaxhighlight>
 +
 +
'''第二种情况:'''首先移动右指针直到不满足要求,再移动左指针直到满足要求,此时记录当前状态,若更优则记录下来。持续如此,直到区间的右边界到达整体的结束点。
 +
<syntaxhighlight lang=python>
 +
left = 0
 +
init state
 +
ret = worse case retval
 +
for right in range(n):
 +
    update state
 +
    while state is not valid:
 +
        left += 1
 +
        update state
 +
    sol = f(left, right)
 +
    if sol is better than ret:
 +
        ret = sol
 
return ret
 
return ret
 
</syntaxhighlight>
 
</syntaxhighlight>
第24行: 第42行:
 
=== [https://leetcode.com/problems/minimum-window-substring/ LeetCode 76. Minimum Window Substring] ===
 
=== [https://leetcode.com/problems/minimum-window-substring/ LeetCode 76. Minimum Window Substring] ===
  
Python 解法:
+
第一种情况。Python 解法:
  
 
<syntaxhighlight lang=python>
 
<syntaxhighlight lang=python>
第52行: 第70行:
 
             if chars[sl] < target[sl]:
 
             if chars[sl] < target[sl]:
 
                 cnt -= 1
 
                 cnt -= 1
 +
    return ret
 +
</syntaxhighlight>
 +
 +
=== LeetCode 340. Longest Substring with At Most K Distinct Characters ===
 +
 +
第二种情况。Python 解法:
 +
 +
<syntaxhighlight lang=python>
 +
def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
 +
    left = 0
 +
    ret = 0
 +
    distinct = 0
 +
    chars = Counter()
 +
    for right, ch in enumerate(s):
 +
        # move the right pointer until the state is invalid
 +
        if chars[ch] == 0:
 +
            distinct += 1
 +
        chars[ch] += 1
 +
        while distinct > k and left <= right:
 +
            # move the left pointer until the state is valid
 +
            c = s[left]
 +
            left += 1
 +
            chars[c] -= 1
 +
            if chars[c] == 0:
 +
                distinct -= 1
 +
        # after the state becomes valid, record the best result
 +
        ret = max(right - left + 1, ret)
 
     return ret
 
     return ret
 
</syntaxhighlight>
 
</syntaxhighlight>

2021年6月15日 (二) 19:29的最新版本

使用左右两个指针,按一定规则向右移动。注意 window 的大小并不一定是固定的。

使用 pattern

[1] [2]

在需要找一个区间的问题中,

第一种情况:首先移动右指针使得满足要求,再移动左指针直到不满足要求,再移动右指针,持续如此,直到区间的右边界到达整体的结束点。

left = 0
init state
ret = worse case retval
for right in range(n):
    update state
    while state is valid:
        sol = f(left, right)
        if sol is better than ret:
            ret = sol
        left += 1
        update state
return ret

第二种情况:首先移动右指针直到不满足要求,再移动左指针直到满足要求,此时记录当前状态,若更优则记录下来。持续如此,直到区间的右边界到达整体的结束点。

left = 0
init state
ret = worse case retval
for right in range(n):
    update state
    while state is not valid:
        left += 1
        update state
    sol = f(left, right)
    if sol is better than ret:
        ret = sol
return ret

相关题目

LeetCode 76. Minimum Window Substring

第一种情况。Python 解法:

def minWindow(self, s: str, t: str) -> str:
    ret = ''
    # cnt: how many chars of t has been covered. just for speeding up the algo
    cnt = 0
    left = 0
    min_size = float('inf')
    chars = Counter()
    target = Counter(t)
                                                                               
    for right, sc in enumerate(s):
        # for a new right pointer, update the state
        chars[sc] += 1
        if chars[sc] <= target[sc]:
            cnt += 1
        # move the left pointer right until the state becomes invalid
        while cnt == len(t):
            if (size := right - left + 1) < min_size:
                min_size = size
                ret = s[left:right + 1]
            # for a new left pointer, update the state
            sl = s[left]
            left += 1
            chars[sl] -= 1
            if chars[sl] < target[sl]:
                cnt -= 1
    return ret

LeetCode 340. Longest Substring with At Most K Distinct Characters

第二种情况。Python 解法:

def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
    left = 0
    ret = 0
    distinct = 0
    chars = Counter()
    for right, ch in enumerate(s):
        # move the right pointer until the state is invalid
        if chars[ch] == 0:
            distinct += 1
        chars[ch] += 1
        while distinct > k and left <= right:
            # move the left pointer until the state is valid
            c = s[left]
            left += 1
            chars[c] -= 1
            if chars[c] == 0:
                distinct -= 1
        # after the state becomes valid, record the best result
        ret = max(right - left + 1, ret)
    return ret

参考资料