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()