代码随想录算法训练营第二天

42 阅读2分钟

209.长度最小的子数组

本题使用滑动窗口的方法。在本题中滑动窗口需要考虑三个问题:

  • 窗口内是什么?
  • 如何移动窗口内的起始位置?
  • 如何移动窗口的结束位置?
    窗口内就是和大于target的长度最小的子数组;当和大于target时,移动起始位置。否则就移动结束位置。
class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left=0;right=0
        min_len=[]
        sub_array=0
        while right <= len(nums)-1:
            sub_array+=nums[right]
            while sub_array>=target:
                min_len.append(right-left+1)
                sub_array-=nums[left]
                left+=1
            right+=1
        return min(min_len) if min_len else 0

59.螺旋矩阵Ⅱ

矩阵之类的题目没有什么统一的方法,关键就是在边界条件的判断。有一点像二分法的开闭区间感觉。

二维矩阵的初始化

res=[[0]*column for _ in range(row)]
class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        cnt=1
        res=[[0]*n for _ in range(n)]
        upper_bound=0;lower_bound=n-1;left_bound=0;right_bound=n-1
        while cnt <= n*n:
            if upper_bound<=lower_bound:
                for i in range(left_bound,right_bound+1):
                    res[upper_bound][i]=cnt
                    cnt+=1
                upper_bound+=1
            if left_bound<=right_bound:
                for j in range(upper_bound,lower_bound+1):
                    res[j][right_bound]=cnt
                    cnt+=1
                right_bound-=1
            if upper_bound<=lower_bound:
                for i in range(right_bound,left_bound-1,-1):
                    res[lower_bound][i]=cnt
                    cnt+=1
                lower_bound-=1
            if left_bound<=right_bound:
                for j in range(lower_bound,upper_bound-1,-1):
                    res[j][left_bound]=cnt
                    cnt+=1
                left_bound+=1
        return res

区间和

涉及区间和类的问题时使用前缀和的方法非常有用。 前缀和的思想是重复利用计算过的子数组之和,从而降低区间查询需要累加计算的次数。

#s是数组
p=[0]*len(s)
pre_sum=0
for i in range(len(s)):
    pre_sum+=s[i]
    p[i]=pre_sum

开发商购买土地

def main():
    import sys
    input = sys.stdin.read
    data = input().split()

    idx = 0
    n = int(data[idx])
    idx += 1
    m = int(data[idx])
    idx += 1
    sum = 0
    vec = []
    for i in range(n):
        row = []
        for j in range(m):
            num = int(data[idx])
            idx += 1
            row.append(num)
            sum += num
        vec.append(row)

    # 统计横向
    horizontal = [0] * n
    for i in range(n):
        for j in range(m):
            horizontal[i] += vec[i][j]

    # 统计纵向
    vertical = [0] * m
    for j in range(m):
        for i in range(n):
            vertical[j] += vec[i][j]

    result = float('inf')
    horizontalCut = 0
    for i in range(n):
        horizontalCut += horizontal[i]
        result = min(result, abs(sum - 2 * horizontalCut))

    verticalCut = 0
    for j in range(m):
        verticalCut += vertical[j]
        result = min(result, abs(sum - 2 * verticalCut))

    print(result)

if __name__ == "__main__":
    main()