这次比赛的题目虽然不难,但比较坑,陷进去了就不好了...
1017. Convert to Base -2
题目大意:将一个十进制的数转换成"-2"进制。
例1:2 -> "110" = (-2)^2 + (-2)^1 = 4 - 2 = 2
例2:3 -> "111" = (-2)^2 + (-2)^0 + (-2)^0 = 4 - 2 + 1 = 3
例3:4 -> "100" = (-2)^2 = 4
这道题目比较坑,实际中有什么应用吗?
不管怎么样,我们先看怎么把十进制数转换成k进制(2<= K<=16)
def convertToBaseK(n, K):
s = ""
while n != 0:
r = n % K # 对K取余
n //= K # n整除以K
s = str(r) + s # 如果r>=10, 用A-F表示
return s
本质就是不断对K取余,然后整除以K,直到n为0为止。
这个过程可以写成
n = (n' * K + r)
= (n'' * K + r') * K + r
= ...
n' = n // K
n'' = n' // K
...
其实对于负的K也是相似的,注意程序中只有负数对负数取余才会得到负数:
3 % (-2) = 1
-1 % (-2) = -1
当r为负数时我们要做一下转换保证r为正数
n = n' * (-2) + (-1)
n' = n // -2
改写成
n = n' * (-2) - 2 + (-1) + 2
n = (n'+1) * (-2) + 1
n = n'' * (-2) + 1
n'' = n' + 1
所以我们需要将新得到的n'的基础上再加1作为下一轮的开始,体现在代码的第15行。
让我们看几个例子:
时间复杂度:O(logn / logk)
空间复杂度:O(logn / logk)
1018. Binary Prefix Divisible By 5
题目大意:问一个2进制的字符串所表示的整数能否被5整除。
这道题没什么好讲的,没必要用bigint。和1015 Smallest Integer Divisible by K差不多,用同余原理即可。
时间复杂度 O(n)
空间复杂度 O(n)
参考代码:
此处应该是广告,能点一下就做好了~
1019. Next Greater Node In Linked List
题目大意:给你一个单向链表,问每个节点后面第一个比它大的节点的值是多少,如果不存在返回0。
Brute Force 就是对每个节点扫描一遍整个链表,时间复杂度是O(n^2),C++居然可以通过(1136ms)!
由于是找第一个比它大的,而不是比它大的中间最小的一个,所以我们不能使用BST的upper_bound。
其实这个题目又是一个换皮的题目,和我们之间讲过的
LC 739. Daily Temperatures
LC 901. Online Stock Span
一样,需要使用到单调栈(monotonic stack),然后从右往左处理。
具体可以看视频讲解(回复 901 或者 1019)。
时间复杂度降低到了O(n)
用空间换时间,空间复杂度O(n)
参考代码:
1020. Number of Enclaves
题目大意:给你一个二维网格,0代表海洋,1代表陆地。你可以认为边框以外全是陆地。问你有多少个格子是孤岛(不和大陆联通的)?
标准题,用DFS来找联通分量并统计大小,走过的地方标记为0。如果这个连通分量能走到边框外面则不是孤岛。注意不能提前剪枝。
时间复杂度:O(mn)
空间复杂度:O(mn)
小优化:可以只从边界上的一圈点开始DFS,但时间复杂度不变。
参考代码: