竞赛地址
https://leetcode-cn.com/contest/biweekly-contest-34/
T1
直接累加,遇到行数为奇数的就减去正中间就好了
class Solution:
def diagonalSum(self, mat: List[List[int]]) -> int:
res = 0
for i in range(len(mat)):
res += mat[i][i]
res += mat[i][len(mat) - i -1]
if len(mat)&1:
res -= mat[len(mat)//2][len(mat)//2]
return res
T2
首先先统计1的个数:
要是不是三的倍数就返回0
要是没有1就返回 (len(s)-1)(len(s)-2)//2,相当于在所有字符串间隔里选出两个,将字符串分成三份。
要是是三的倍数就分开统计
class Solution:
def numWays(self, s: str) -> int:
num_1 = s.count('1')
if num_1 % 3:
return 0
if not num_1:
return ((len(s) - 1)*(len(s) - 2)//2) %(10**9+7)
cnt = 0
cnt_01 = 1
cnt_02 = 1
for i , ch in enumerate(s):
if ch == '1':
cnt += 1
else:
if i and cnt == num_1 // 3:
cnt_01+=1
if cnt_01 and cnt == num_1 // 3 * 2:
cnt_02+=1
return (cnt_01 * cnt_02) % (10**9 + 7)
T3
由于删除的是子数组不是子序列,所以剩余的部分一定包含头尾,所以使用双指针。
指针分别指向头尾的两个最长递增子数组的起始位置。
然后分别移动左右指针来得到最长递增序列。
总之写的时候非常暴躁,最后甚至不想优化(
class Solution:
def findLengthOfShortestSubarray(self, arr: List[int]) -> int:
l , r = 0 ,len(arr)-1
while l<len(arr)-1 and arr[l+1]>=arr[l]:
l += 1
if l==r:
return 0
while r>0 and arr[r]>=arr[r-1]:
r-=1
left=arr[0:l+1]
right=arr[r:len(arr)]
while left and left[-1]>arr[r]:
left.pop()
while right and right[0]<arr[l]:
right.pop(0)
return len(arr)-max(map(len,(left+arr[r:len(arr)],arr[0:l+1]+right)))
T4
直接动态规划
dp[f][r]表示花费r单位燃料到达f城则
dp[f][r]=dp[f][r]+dp[s][r-abs(s-f)]
class Solution:
def countRoutes(self, locations: List[int], start: int, finish: int, fuel: int) -> int:
n = len(locations)
f = [[0] * (fuel+1) for _ in range(n)]
f[start][0] = 1
for i in range(fuel):
for j in range(n):
for k in range(n):
if(j!=k):
r = i+abs(locations[j]-locations[k])
if(r <= fuel):
f[k][r] = (f[k][r] + f[j][i]) % 1000000007
ans = 0
for i in range(fuel+1):
ans += f[finish][i]
return ans % 1000000007