剑指offer-Python3版(十一)
整数中1出现的次数
Q: 输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。
例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。
思路
一开始只想到了这种,但运行很慢,力扣通不过,pass
class Solution:
def countDigitOne(self, n: int) -> int:
"""
输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。
例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。
:param n:
:return:
"""
one_count = 0
for i in range(1, n + 1):
while i > 1:
j = i % 10
if j == 1:
one_count += 1
i = int(i / 10)
if i == 1:
one_count += 1
return one_count
网上有这种算法
记n的第i位为ni,记ni " 为当前位,记为cur,左边的称为高位,记为high,右边的记为低位,记为low,10i称为位因子,记为digit
cur = 0 1出现的次数只由高位high决定 = high*dight
cur = 1 1出现的次数由high和low决定 = high*digit+low+1
cur >1 1出现的次数只由high决定 = (high+1)*digit
class Solution:
def countDigitOne(self, n: int) -> int:
"""
输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。
例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。
:param n:
:return:
"""
digit, res = 1, 0
high, cur, low = n // 10, n % 10, 0
while high != 0 or cur != 0:
if cur == 0:
res += high * digit
elif cur == 1:
res += high * digit + low + 1
else:
res += (high + 1) * digit
low += cur * digit
cur = high % 10
high //= 10
digit *= 10
return res
把数组排成最小的数
Q:输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
思路
class cmpSmaller(str):
def __lt__(self, other):
return self + other < other + self
class Solution:
def minNumber(self, nums: [int]) -> str:
res = sorted(map(str, nums), key=cmpSmaller)
smallest = ''.join(res)
return smallest
丑数
Q:我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。
class Solution:
def nthUglyNumber(self, n: int) -> int:
dp, a, b, c = [1] * n, 0, 0, 0
for i in range(1, n):
n2, n3, n5 = dp[a] * 2, dp[b] * 3, dp[c] * 5
dp[i] = min(n2, n3, n5)
# 3个if防止重复丑数
if dp[i] == n2:
a += 1
if dp[i] == n3:
b += 1
if dp[i] == n5:
c += 1
return dp[-1]
n=3 程序流程
dp=[1, 1, 1] a=0,b=0,c=0
i=1
n2=2 n3=3 n5=5
i==1 dp[i]==2
a== 1
i=2
n2=4 n3=3 n5=5
i==2 dp[i]==3
b== 1
dp[n]= 3
本文深入解析《剑指Offer》中三个经典算法题目:计算整数中1出现的次数,将数组排列成最小数值,及寻找第n个丑数。通过Python3实现,提供高效算法思路。

1万+

被折叠的 条评论
为什么被折叠?



