130th 周赛总结

总结反思

Posted by Pacras on March 31, 2019

       本周的题目是比较简单的,也有一些启发性。

1.可被5整除的二进制前缀

       这个题不难直接判断就可以,即

t = t * 2 + A[i]
res.append(t % 5 == 0)

但是可以被5整除的数有一个特点,个位为 0 或者 5,为了避免 t 过大,可以修改为 t = (t*2 + A[i]) % 5

2.负二进制转换

       -2进制,Emmmmm,第一眼看上去有些复杂,其实和二进制一样,除以基直至0,最后把余数连起来就可以了。要注意的是余数不能为负数,也就是不能为-1。什么情况下会出现余数为 -1 的情况呢?当数字为负数且不能整除时,这个时候给商加一即可。

while N != 0 :
   if N < 0 and N % -2 != 0:
        d = int(N / -2) + 1
    else:
	d = int(N / -2)
        s  = str(N - d*(-2)) + s
    N = d

3.链表中的下一个更大节点

       可以用暴力法去做,最坏的情况下链表时递减的,时间复杂度为 O(n^2)。然后想到可以将暂时没有找到下一个更大节点的值保存到栈中,在遍历的过程中若栈顶元素小于当前节点的值,则说明栈顶元素找到了下一个更大的节点。循环直至栈空或者栈顶元素大于等于当前节点的值。要注意的时,栈内不能只保存节点的值,还应保存在节点在链表中的位置。

i = 0
while head:
   while stack and stack[-1][1] < head.val:
       res[stack.pop()[0]] = head.val
       stack.append((i, head.val))
   # 先填上 0 
   res.append(0)
   i += 1
   head = head.next

4.飞地的数量

       这道题用 dfs将边界上的 1 和可以延伸到的 1 置为 0,然后统计剩下的 1即可。

dfs(i, j):
   A[i][j] = 0
   dx = [-1, 1, 0, 0]
   dy = [0, 0, -1, 1]
   for in range(4):
       x, y = i + dx, j + dy
       if 0 <= x < m and 0 <= y < n and A[x][y] == 1:
           dfs(x, y)
for i in range(self.m):
   for j in range(self.n):
       if (i*j == 0 or i==self.m-1 or j==self.n-1) and self.A[i][j] == 1:
           dfs(i, j)
res = 0
for i in range(m):
   for j in range(self.n):
       if self.A[i][j] == 1:
           res += 1
return res