Day2 打卡~

LC 209 长度最小的子数组

寻找满足条件的最小长度子数组,考虑使用滑动窗口。for循环控制窗口的右边界,j指针初始化为0,指向窗口左边界。窗口中元素和大于target时,减去nums[j],j += 1,实现窗口的移动。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        res = float('inf')
        sum , j , n = 0 , 0 , len(nums)
        for i in range(n):

            sum += nums[i] #计算窗口中元素的和,拿去跟target比较
            while sum >= target:
                sum -= nums[j]
                res = min(res , i - j + 1)
                j += 1
        if j == 0 and sum < target: #若窗口取到整个数组,都没tartget大,就return 0
            return 0
        return res

要注意判断 sum和target的大小时,得用while而不是if,后者只能判断一次,无法处理[1,1,1,100]这种极端情况。

LC 59 螺旋矩阵

懵逼的一道题,直接看讲解了。。。

矩阵的表示方法(例如要生成一个m行 * n列,全为零的矩阵):[ [0] * n for _ in range(m) ].

本题模拟螺旋矩阵的方法就是一圈一圈的生成,总共需要转 n // 2圈,模拟这个转圈的过程,一层一层的往里面填充数字即可。注意每一行生成时要遵守同一个规则:左闭右开(也可其他区间形式,具体情况具体分析),这样才保证不会乱。

注意,因为是从外到内逐层处理,因此for循环开始的数是随着层数变的,因此一开始就用top,bottom等等变量定义好,方便后续层数变化做改变

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        res = [[0] * n for i in range(n)]
        top , bottom ,left , right =  0 , n-1 , 0 , n-1
        insert = 1
        while top <= bottom and left <= right:
            #从左到右,处理上边界
            for i in range( left , right):
                res[top][i] = insert
                insert += 1
            #从上到下,处理右边界
            for i in range(top , bottom):
                res[i][right] = insert
                insert += 1
            #从右到左,处理下边界
            for i in range(right , left , -1):
                res[bottom][i] = insert
                insert += 1
            #从下到上,处理左边界
            for i in range(bottom , top , -1):
                res[i][left] = insert
                insert += 1
            top += 1
            bottom -= 1
            left += 1
            right -= 1
        #提交的时候发现奇数的情况最中心的元素没处理,单独加一行判断AC了
        if n % 2 == 1:
            res[n//2][n//2] = n**2
        return res

卡玛58 区间和

要求一个数组A的[a,b]区间内元素和,可以先写一个数组Pre,存储数组A从头开始的累加和,即P3=A[0]+A[1] +A[2]+A[3],若要求数组子区间1-3的元素和,用P3-P0即可。

def func():
    n = int(input())
    a = [0] * n
    for i in range(n):
        a[i] = int(input())
    pre = [0] * n 
    data = 0
    for i in range(n):
        data += a[i]
        pre[i] = data
    while True:
        try:
            ls = input().split(' ')
            start = int(ls[0])
            end = int(ls[1])
            if start == 0:
                sum = pre[end]
                print(sum)
            else:
                sum = pre[end] - pre[start-1]
                print(sum)
        except:
            break

func()

注意因为涉及到Pre[start-1]这种写法,要单独讨论一下区间左端点为0的情况,不然产生负数。

本题一开始用暴力法,发现超时了,原因是有长度特别长的数组,有m个子区间要求,总复杂度为O(m×n),而利用前缀和的思想,生成pre数组O(n),查询的复杂度仅为O(1),避免了超时。

卡玛44 开发商购买土地

思路:

先按题意生成土地价值矩阵,之后就有两种切分方式:横着或竖着。竖着切的话,我们可以构造一个前缀和数组,表示前i列土地价值之和。之后,假设A公司分到的是第一列土地,那么B公司的土地价值就是总价值减掉A的土地价值,要求两家公司价值差,那么就用土地总价值减掉两倍的A公司土地价值即可。

下为代码,写的有点繁琐,第一次写这种题,连矩阵怎么构造都花了半天时间,无语凝噎ing。。并且感觉这个题想到使用前缀和也不是很容易,反正我没想到。。。

def func():
    data= input().split(' ')
    m , n = int(data[1]) , int(data[0])
    
    array = [[0]*m for _ in range(n)]
    for i in range(n):
        nums = input().split(' ')
        for j in range(m):
            array[i][j] = int(nums[j])
    
    #横着切分
    pre_row = [0] * n
    sum = 0
    for i in range(n):
        for j in range(m):
            sum += array[i][j]
        pre_row[i] = sum
    dif_row = float('inf')
    for a in range(n):
        dif_row = min(dif_row , abs(pre_row[n-1] - pre_row[a]*2))
    
    #竖着切分
    pre_column = [0] * m 
    sum_column = 0
    for i in range(m):
        for j in range(n):
            sum_column += array[j][i]
        pre_column[i] = sum_column
    
    dif_column = float('inf')
    for a in range(m):
        dif_column = min(dif_column,abs(pre_column[m-1]-pre_column[a]*2))
    
    print(min(dif_column,dif_row))
func()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值