代码随想录算法训练营第二天 | 数组part02
209.长度最小的子数组
滑动窗口,理解其概念很重要。说白了就是双指针这次一起移动了。
上一个题目是一头一尾,这一次直接都从头进行移动,然后看看满足条件的尾指针-头指针的长度是几即可
slow , fast = 0 , 0
sum_ = 0
max_ = 99999999
while fast < len(nums):
sum_ += nums[fast]
while sum_ >= target:
min_ = fast - slow + 1
max_ = min_ if max_ > min_ else max_
sum -= nums[slow]
slow += 1
fast += 1
return 0 if max_ == 99999999 else max_
59.螺旋矩阵II
转圈,仅此而已,不过需要注意循环不变量,保证每圈每行的代码差不多,可以进行复用。
保证每圈的代码可以复用。
谁不变用谁:nums中横着的时候x不变,所以用x,竖着的时候y不变,所以用y
yxyx原则:range中的范围是谁变用谁
# 首先应该知道转多少圈,n=2的话是1圈,n=4的话是2圈,所以应该是n/2圈、
# 那如果n是奇数怎么办,最后在正中间补充一个数就好了,
# 如何确定转到第几圈了,定义一个变量offset用来存储转到第几圈了
offset = 1
loop = n // 2
mid = n // 2
startx , starty = 0 , 0
count = 1
while (offset < loop):
for j in range(starty,n-offset):
nums[startx][j] = count
count += 1
for i in range(startx,n-offset):
nums[i][n-offset] = count
count += 1
for j in range(n-offset,starty,-1):
nums[n-offset][j] = count
count += 1
for i in range(n-offset,startx,-1):
nums[i][starty] = count
count += 1
startx += 1
starty += 1
offset += 1
if n % 2 != 0 :
nums[mid][mid] = count
return nums
58.区间和
www.programmercarl.com/kamacoder/0…
前缀和 在涉及计算区间和的问题时非常有用!
理解起来很简单,不过就是两个列表,第一个列表是原来的数,第二个列表存的数是前n个数的和
第二个列表中,第n个数就对应前n个数的和
n = int(input())
nums = []
sum_ = []
sum1 = 0
for i in range(n):
a = int(input())
sum1 += a
nums.append(a)
sum_.append(sum1)
while(True):
try:
a,b = map(int,input().split())
if a == 0:
print(sum_[b])
else:
print(sum_[b] - sum_[a-1])
except:
break
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.开发商购买土地
思路很简单。
首先是获取所有的输入,然后构建一个包含列表中所有元素的列表。这里需要注意,需要构造一个二维列表。
然后就可以求前序和,行的前序和求一遍,列的前序和求一边。
之后可以利用差值(abs - 2*前序和) 来和result进行比较。(行和列的都需要比一下)
提示:如果不会做的话,可以弄成2行3列的,就会看角标了。
import sys
input = sys.stdin.read
def main():
data = input().split()
index = 0
n = int(data[index])
index += 1
m = int(data[index])
index += 1
# 到此为止取到了前两个数,现在我们需要写一个列表来存储起来n行m列个数据
vec = []
sum_ = 0 # 同时来计算所有数的和
for i in range(n):
res = []
for j in range(m):
num = int(data[index])
index += 1
res.append(num)
sum_ += num
vec.append(res)
# 到此位置将列表中的所有元素都进行了存储
# 现在需要计算按行求前序和 以及 按列求前序和
# 按行
hang = [0] * n
for i in range(n):
for j in range(m):
hang[i] += vec[i][j]
# 按列
lie = [0] * m
for i in range(m):
for j in range(n):
lie[i] += vec[j][i]
# 现在按行按列的前序和都有了,就可以进行计算了
# 计算的时候需要注意,需要有一个数来存储最小值
result = float('inf')
# 遍历行的前序和
# 首先需要知道第一行是hang[0] 然后sum-hang[0] 是两个只差
# hang[0] - (sum -hang[0]) = abs(sum-2*hang[0)
hanghe = 0
for i in range(n):
hanghe += hang[i]
result = min(result,abs(sum_ - 2*hanghe))
liehe = 0
for j in range(m):
liehe += lie[j]
result = min(result,abs(sum_ - 2*liehe))
print(result)
if __name__ == '__main__':
main()