LC 209, 904, 76, 59 Sliding-Window Problems

LC 209, 904, 76, 59 Sliding-Window Problems


Second part of Array, (List in python, I guess). LC977 is covered in the last post already.

LC 209. Minimum Size Subarray Sum


From the first site, the brute force method should be clear. Where from here, #
209.长度最小的子数组
, the sliding window method is introduced, which helps to reduce the Time complexity to just O ( n ) O(n) O(n).


# LC 209
# Credit to Carl
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
    ret = len(nums) + 1
    for i in range(len(nums)):
        acc = 0
        for j in range(i, len(nums)):
            acc += nums[j]
            if acc >= target:
                ret = min(ret, j - i + 1)
                break
    return 0 if ret > len(nums) else ret

Logic

If we divide two cases, we can bring the inner while loop out, where:

  • Condition Unfulfilled (feeding the condition):

    • When: sum(nums[i,j+1]) < 0, at this time, the current sum is not enough yet.
    • Action: If the sum is not enough, we could just add more numbers, then the left bound move to the right.
  • Condition Fulfilled:

    • When: sum(nums[i,j+1]) >= 0.
    • Action: the left bound could move to the right, to reach the array with the least length.
      • In the above code, As long as the condition is reached, the shortest array is calculated without disruptions. It will sort of converges quicker than the below code (on first site, but actually speed is the same).
def min_sub_array_len(self, target: int, nums: List[int]) -> int:
    low = 0
    high = -1
    acc = 0
    count = len(nums) + 1
    while low < len(nums):
        # feeding the condition
        if acc < target:
            high += 1
            # higher bound reached the limit
            # but the condition is not yet met
            if high >= len(nums):
                break
            acc += nums[high]
        else:
            # condition fulfilled
            count = min(count, high - low + 1)
            acc -= nums[low]
            low += 1
    return count if len(nums) >= count else 0

LC 904. Fruit Into Baskets


904. Fruit Into Baskets

Well, look a bit of disgusting, who actually plants fruits like that? Straight to hell. Anyway, this question looks also like a sliding-window question, but the condition to check upon on is not so easy.

Logic

  • Firstly, I run-length encoded the input, so that input of [ 1 , 1 , 1 , 2 , 2 , 3 , 2 , 2 ] [1,1,1,2,2,3,2,2] [1,1,1,2,2,3,2,2] becomes [ 1 : 3 , 2 : 2 , 3 : 1 , 2 : 2 ] [1:3, 2:2, 3:1, 2:2] [1:3,2:2,3:1,2:2], where ( k e y , v a l u e ) (key, value) (key,value) pairs corresponds to the ( t y p e , f r e q u e n c e ) (type, frequence) (type,frequence).

Gradly, we have a window of fix size two, where window.size == len(basket).

  • Condition Unfulfilled (throw away to fit):

    • When: len(basket) > 2, at this time, we are not feeding more to fulfill the condition, we need to take things out. However, we can’t just throw out everything that is in the window, the last occurance is still usable, and should be tested in the next window. For example, after testing the window of [ 1 : 3 , 2 : 2 ] [1:3, 2:2] [1:3,2:2], we should then choose the window of [ 2 : 2 , 3 : 1 ] [2:2, 3:1] [2:2,3:1].
    • Action: Take the left bound to be the last occurance.
  • Condition Fulfilled:

    • When: len(basket) <= 2.
    • Action: Take in more trees to see if they fit.

LC 76. Minimum Window Substring


76. Minimum Window Substring

Logic:

  • Analogue to a slide window problem.

  • Condition Unfulfilled (feeding the condition):

    • When: counter of s[i,j+1] < counter of [t], where counter only counts for the characters that are in t.
    • Action: Move the left bound j left.
  • Condition Fulfilled:

    • When: counter of s[i,j+1] < counter of [t].
    • Action: Move the right bound i left.
  • Notice: if t = "ABC", we are not necessarily one step closer if we seee any of A, B or C in s, we only need 1 occurance of each, and no more.

  • However, if there is more in the substring when we move right bound i, we should also remember that, and the condition is only break when not enough chars are included.

def minWindow(self, s: str, t: str) -> str:
    if len(s) < len(t) or t == "":
        return ""
    s_lst = list(s)
    t_lst = list(t)
    t_ct = Counter(t_lst)
    acc_ct = t_ct.copy()
    length = len(s_lst)
    # total char to match
    total_count = len(t_lst)
    # current best choise
    min_len = len(s_lst) + 1
    start, end = -1, 0
    for i in acc_ct:
        acc_ct[i] = 0
    # left
    i = 0
    # right
    j = 0
    while j < length:
        c = s[j]
        if c in acc_ct:
            # cur state change
            if acc_ct[c] < t_ct[c]:
                total_count -= 1
            acc_ct[c] += 1
            if total_count <= 0:
                while total_count == 0:
                    if j - i + 1 < min_len:
                        end = j
                        start = i
                        min_len = j - i + 1
                    c2 = s[i]
                    if c2 in acc_ct:
                        acc_ct[c2] -= 1
                        # there is already not enough char in [start:end+1]
                        if acc_ct[c2] < t_ct[c2]:
                            total_count += 1
                    i += 1
        j += 1
    # start, end not found
    if start == -1:
        return ""
    return s[start : end + 1]

LC 59


59.螺旋矩阵II

Logic:

  • Simulation, not much to add, easy for me. Just remember the boundary conditions.

Summary:


  • Figure out when the condition is fulfilled, and when is not, then sliding-window problems are not so difficult, and they will even be elegant.

  • Total time: About a whole afternoon.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值