LeetCode 600 Non-negative Integers without Consecutive Ones
第一次ak哈哈,可能是因为这周的比赛比较简单。
先说第一个方法,也是我当时想出来的。分情况讨论,一种是二进制表示的长度小于n的长度,另一种是跟n长度相同。第一种情况任意不含11的数都符合条件,第二种要搜索判断。
class Solution:
def count(self, i, num, size):
if i == size - 1:
return 1
if num == 1:
return self.count(i+1, 0, size)
else:
return self.count(i+1, 0, size) + self.count(i+1, 1, size)
# top: whether current value is the same as a
def countLimit(self, i, num, size, a, top):
if top and num > a[i]:
return 0
if i == size - 1:
return 1
if num < a[i]:
top = False
if num == 1:
if top == False:
# we can choose whatever we want
return self.all[size-i]
return self.countLimit(i+1, 0, size, a, top)
else:
return self.countLimit(i+1, 0, size, a, top) + self.countLimit(i+1, 1, size, a, top)
def findIntegers(self, num):
"""
:type num: int
:rtype: int
"""
# possible solutions starting with 1
self.all = [0] * 31
self.all[1] = 1
self.all[2] = 1
for i in range(3, 31):
self.all[i] = self.all[i-1] + self.all[i-2]
a = []
while num > 0:
a.append(num % 2)
num = num // 2
a.reverse()
length = len(a)
#print(a)
res = self.countLimit(0, 1, length, a, True)
#print(res)
for i in range(1, length):
res += self.all[i]
# add 0 to solutions
return res + 1
all数组表示1开头符合条件的数的数量,本来是通过count函数来搜索的,后来发现是斐波那契数列就直接算了。countLimit用来搜索长度与n相同的数,top用来标记当前位是否与n一样大,如果当前第i位是1并且已经不是最大的,那就说明从第i位开始就可以随意选1和0了,加了这个剪枝就过了。
下面是官方题解的思路,另外参考这个解释。 这个f[i]包含以0开头的情况,所以如果发现n的第i位是1,那么当前位是0,后面就可以任意选数字了。如果遇到连续的1,选完第i位是0,就可以退出了,因为此时第i位只能为0。最后返回时加上n本身(如果遇到11要限减掉,因为不可能出现n这个数)。
class Solution:
def findIntegers(self, num):
"""
:type num: int
:rtype: int
"""
a = []
while num > 0:
a.append(num % 2)
num = num // 2
a.reverse()
length = len(a)
# number of available solutions, i is the length of binary representations
# f[1]: 0, 1; f[2]: 00, 10, 01
f = [0] * (length+1)
f[0] = 1
f[1] = 2
for i in range(2, len(f)):
# f[i] = (f[i-1] + '0') + (f[i-2] + '01')
f[i] = f[i-1] + f[i-2]
res = 0
#print(length,res)
for i in range(0, length):
if a[i] == 1:
l = length - i - 1
res += f[l]
if i > 0 and a[i-1] == 1:
# num itself is invalid and will be deleted later
res -= 1
# res was updated in previous i
break
# plus num itself
return res+1
comments powered by Disqus