LeetCode Contest 167
上次参加 leetcode 比赛还是去年四月份的时候了。回想的时候总觉得时间过得很快。只是一年,以前一起比赛的小伙伴们包括我自己都已经离开哥村了。
第一题Convert Binary Number in a Linked List to Integer
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getDecimalValue(self, head: ListNode) -> int:
r = 0
while head:
r = r * 2 + head.val
head = head.next
return r
第二题Sequential Digits
我一开始觉得这题很麻烦,先做了第三题。再次读题的时候我发现我可以枚举所有“后面一位数字比前面一位大1”的数,然后保留low
和 high
之间的数就行。
class Solution:
def sequentialDigits(self, low: int, high: int) -> List[int]:
ret = []
for s in range(1, 10):
c = s
i = s + 1
while c < high and i < 10:
c = c * 10 + i
i += 1
if low <= c <= high:
ret.append(c)
ret.sort()
return ret
第三题Maximum Side Length of a Square with Sum Less than or Equal to Threshold
对正方形数组的边长做二分查找。
class Solution:
def maxSideLength(self, mat: List[List[int]], threshold: int) -> int:
# 预处理,方便查询数组中矩形区域的和
n = len(mat)
m = len(mat[0])
s = [[0] * (m + 1) for _ in range(n + 1)]
for i in range(n):
for j in range(m):
s[i][j] = s[i-1][j] + s[i][j-1] + mat[i][j] - s[i-1][j-1]
# 判断是否存在边长为 c 的所有数字之和小于 threshold 的正方形区域
def check(c):
for i in range(n-c+1):
for j in range(m-c+1):
if s[i+c-1][j+c-1] - s[i-1][j+c-1] - s[i+c-1][j-1] + s[i-1][j-1] <= threshold:
return True
return False
# 二分查找
a = 0
b = min(n, m)
r = 0
while a <= b:
c = (a + b) // 2
if check(c):
r = c
a = c + 1
else:
b = c - 1
return r
第四题Shortest Path in a Grid with Obstacles Elimination
一开始以为可以动态规划,但是没有想出来。于是直接就深度搜索+剪枝了。我一开始就做了一个剪枝:如果当前的搜索路径长度已经大于已有的路径的长度,那么就没有必要继续下去了。不幸的是,这个算法TLE了。然后我又想到了另一个明显的剪枝:如果现在找到的答案已经是最小的,那么就没有必要搜索下去了。没有想到加上这个剪枝就过了。
class Solution:
def shortestPath(self, grid: List[List[int]], k: int) -> int:
n = len(grid)
m = len(grid[0])
ans = [-1]
visited = [[False] * m for _ in range(n)]
def dfs(x, y, s, c):
if ans[0] == (n+m-2) or ans[0] != -1 and ans[0] < s:
return
if x == n-1 and y == m-1:
ans[0] = s
return
for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
cx = x + dx
cy = y + dy
if cx < 0 or cy < 0 or cx >= n or cy >= m or visited[cx][cy]:
continue
visited[cx][cy] = True
if (grid[cx][cy] == 0):
dfs(cx, cy, s+1, c)
elif c > 0:
dfs(cx, cy, s+1, c-1)
visited[cx][cy] = False
visited[0][0] = True
dfs(0, 0, 0, k)
return ans[0]