Leetcode刷题笔记1 - 数组基础2

Leetcode 209 长度最小的子数组

        对于子数组的定义,并不像集合中的子集,子数组是原数组的连续部分,因此每个子数组都是通过选择一个起始位置和结束位置来构造的。

 暴力解法

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        # 这种解法时间复杂度较高,在leetocode中判题时会遇到超时的情况
        min_length = float('inf')
        n = len(nums)
        for i in range(n):
            sum = 0
            for j in range(i, n):
                sum += nums[j]
                if sum >= target:
                    min_length = min(min_length, j - i + 1)
                    break
        return min_length if min_length != float('inf') else 0
    

滑动窗口解法

        滑动窗口解法我理解的就是在数组的子数组中找出一个大于等于target的,如果sum > target就去除前面的元素,直到sum < target,然后继续向前寻找下一个合适的子数组。类似与载客车,多一名乘客就超载,下去一个。具体解法如下:

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        i, min_length, n = 0, float('inf'), len(nums)
        sum = 0
        for j in range(n):
            sum += nums[j]
            while sum >= target:
                min_length = min(min_length, j - i + 1)
                sum -= nums[i]
                i += 1
        return min_length if min_length != float('inf') else 0

Leetcode 59 螺旋矩阵 ||

        此题我认为考验边界问题已经代码控制能力,需要注意的是循环不变量以及边界问题。

        在这题中向左和向上我的边界判断都有问题,应该是range(y, starty, -1)而不是range(y, 0, -1)因为在n>3时里面螺旋不止一层,所以y的终止需要更新。

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        loop, mid = n // 2, n // 2
        offset = 1
        startx, starty = 0, 0
        count = 1
        matrix = [[0 for _ in range(n)]for i in range(n)]
        while loop:
            i, j = startx, starty
            for r in range(j, n - offset):
                matrix[i][r] = count
                count += 1
                j += 1
            for b in range(i, n - offset):
                matrix[b][j] = count
                count += 1
                i += 1
            for l in range(j, starty, -1):
                matrix[i][l] = count
                count += 1
                j -= 1
            for t in range(i, startx, -1):
                matrix[t][j] = count
                count += 1
                i -= 1
            startx += 1
            starty += 1
            offset += 1
            loop -= 1
        if n % 2:
            matrix[mid][mid] = count
        return matrix

 卡码网58. 区间和

此题的要点在于前缀,我理解的就是先设个数组记录前n项和,然后再index调用时只用两个数组两个元素就可以。同时通过这两个卡码网的题目可以有效了解到了acm输入输出。明天再复习一遍

import sys
input = sys.stdin.read

def main():
    data = input().split()
    index = 0
    n = int(data[index])
    index += 1 
    vec = []
    for i in range(n):
        vec.append(int(data[index + i]))
    index += n 
    p = [0] * n 
    presum = 0
    for i in range(n):
        presum += vec[i]
        p[i] = presum
    results = []
    while index < len(data):
        a = int(data[index])
        b = int(data[index + 1])
        index += 2
        if a == 0:
            sum_value = p[b]
        else:
            sum_value = p[b] - p[a - 1]
        results.append(sum_value)
    for result in results:
        print(result)

if __name__ == "__main__":
    main()

 卡码网44.开发商购买土地

此题可以使用前缀和暴力优化两种方法:

前缀法就是先计算行和列的数据,再分别处理比较大小

暴力优化是在暴力枚举时进行result计算

import sys
input = sys.stdin.read 

def main():
    data = input().split()
    index = 2  
    n, m = int(data[0]), int(data[1])
    vec = []
    sum = 0
    for i in range(n):
        row =[]
        for j in range(m):
            num = int(data[index])
            index += 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值