LintCode刷起来(一)
1. A + B 问题
- 方法一:
class Solution:
"""
@param a: An integer
@param b: An integer
@return: The sum of a and b
"""
def aplusb(self, a, b):
# write your code here
return a + b
- 方法二:
class Solution:
"""
@param a: An integer
@param b: An integer
@return: The sum of a and b
"""
def aplusb(self, a, b):
# write your code here
return sum([a, b])
- 方法三:
from operator import add
class Solution:
"""
@param a: An integer
@param b: An integer
@return: The sum of a and b
"""
def aplusb(self, a, b):
# write your code here
return add(a, b)
2 · 尾部的零
大佬救命,大佬饶命
大佬还是大佬,太强了。想要知道有多少个0也就是里面有这n个数可以拆分出来多少个2和5。很显然5的个数远远小于2的个数,所以这n个数可以拆分出来多少个5也就是多少个0.
不得不说大佬思路太强了。下面也就是找1234···n-1n里面可以拆分出多少个5了很显然5的倍数必定可以拆分出至少一个5,同时25的倍数可以拆分出至少两个5,依次类推,5^i次方至少可以拆分出来i个5,我们可以第一次只统计5的倍数,然后5 ^ 2的倍数依次类推到5 ^ i的倍数,所有个数加起来即可。
class Solution:
"""
@param n: A long integer
@return: An integer, denote the number of trailing zeros in n!
"""
def trailingZeros(self, n):
# write your code here
num = 0
i = 5
while n>=i:
num += n//i
i = i * 5
return num
3 · 统计数字
- 方法一:偷个懒直接用python的内置函数 cout来做,可以用来查找一个字符串中指定字符的个数
class Solution:
"""
@param k: An integer
@param n: An integer
@return: An integer denote the count of digit k in 1..n
"""
def digitCounts(self, k, n):
# write your code here
result = 0
for item in range(0, n+1):
number = str(item).count(str(k))
result += number
return result
- 方法二:
笨笨的方法对每个数都进行统计,能力所限,懒得优化了,据大佬说可以优化到O(logN)
class Solution:
"""
@param k: An integer
@param n: An integer
@return: An integer denote the count of digit k in 1..n
"""
def digitCounts(self, k, n):
# write your code here
result = 0
if k == 0 :
result += 1
for i in range(n+1):
temp = i
while temp:
if temp % 10 == k:
result +=1
temp//=10
return result
- 方法三:大佬的方法,感兴趣的看看就好
class Solution:
"""
@param: : An integer
@param: : An integer
@return: An integer denote the count of digit k in 1..n
"""
def digitCounts(self, k, n):
def ten(power):
return 10**power
digits = self.getNumOfDigits(n)
ans = 0
if k == 0:
for i in range(digits-1):
ans += (n // ten(i+1) -1) * ten(i)
ans += min(n % ten(i+1), ten(i) - 1) + 1
ans += 1
else:
for i in range(digits):
ans += n // ten(i+1) * ten(i)
ans += max(0, min( (k+1)*ten(i)-1, n%ten(i+1) ) - k*ten(i) + 1)
return ans
@staticmethod
def getNumOfDigits(n):
if n == 0:
return 1
count = 0
while n:
count += 1
n //= 10
return count
4 · 丑数 II
其实思路很明确也很简单,枚举肯定最麻烦而且也不可取。由于整数均可以划分为素数不同幂次的乘积且只有一种情况。只有质因子2、3、5所以它必定是这三个数的不同幂次的乘积,所以我们只需要有效到大依次找到并且第N个就好了。
class Solution:
"""
@param n: An integer
@return: the nth prime number as description.
"""
def nthUglyNumber(self, n):
# write your code here
heap = [1]
p2,p3,p5 = 0,0,0
for i in range(n - 1):
last = heap[-1]
while heap[p2] * 2 <= last:
p2 += 1
while heap[p3] * 3 <= last:
p3 += 1
while heap[p5] * 5 <= last:
p5 += 1
heap.append(min(heap[p2] * 2, heap[p3] * 3, heap[p5] * 5))
return heap[-1]
我看网上还有一种堆排序的算法也是可以的
seen采用元组的因为查找方便,运用了空间换时间的方法
求第n小的丑数,可以采用最小堆来解决。每次弹出堆中最小的丑数,然后检查它分别乘以2、3和 5后的数是否生成过,如果是第一次生成,那么就放入堆中。第n个弹出的数即为第n小的丑数。
至于为什么要判断是否生成过,因为如果最小为2的时候4,6,10会放入,但是当最小为3时6,9,10也会放入,同理5最小时10,15,25也会放入。这样可以将重复的6和10排除,方便堆排序
import heapq
class Solution:
"""
@param n: An integer
@return: return a integer as description.
"""
def nthUglyNumber(self, n):
heap = []
heapq.heappush(heap, 1)
seen = set()
seen.add(1)
factors = [2, 3, 5]
curr_ugly = 1
for _ in range(n):
# 每次弹出当前最小丑数
curr_ugly = heapq.heappop(heap)
# 生成新的丑数
for f in factors:
new_ugly = curr_ugly * f
if new_ugly not in seen:
seen.add(new_ugly)
heapq.heappush(heap, new_ugly)
return curr_ugly