题43:1~n整数中1出现的次数
这道题从思路上都没转换过来,最初试图分段统计,但正确思路是计算每个数位上可能出现的1的次数
详细分析见👉王先生的题解
法一:我的版本相对复杂一点,没有正解简洁
class Solution:
def countDigitOne(self, n: int) -> int:
ans,s=0,str(n)
for i in range(len(s)):
high,low=s[:i],s[i+1:]
if s[i]=='0':
h=int(high) if len(high)!=0 else 0
l=10**len(low) if len(low)!=0 else 1 #即正解里的digit
ans+=h*l
elif s[i]=='1':
if len(high)==0:
ans+=int(low)+1 if len(low)!=0 else 1
else:
ans+=int(low)+1 if len(low)!=0 else 1
h=int(high)
l=10**len(low) if len(low)!=0 else 1
ans+=h*l
else:
h=int(high)+1 if len(high)!=0 else 1
l=10**len(low) if len(low)!=0 else 1
ans+=h*l
#print(s[i],high,low,h,l,ans)
return ans
正解:
按思路自己写的:
class Solution:
def countDigitOne(self, n: int) -> int:
high,low,digit,ans,tmp=0,0,1,0,n
while tmp!=0:
cur,tmp=tmp%10,int(tmp/10)
high,low=tmp,n-tmp*digit*10-cur*digit
if cur==0:
ans+=high*digit
elif cur==1:
ans+=high*digit+low+1
else:
ans+=(high+1)*digit
digit*=10
return ans
更简洁版:
class Solution:
def countDigitOne(self, n: int) -> int:
high,low,cur,digit,ans=n//10,0,n%10,1,0
while high!=0 or cur!=0:
if cur==0:
ans+=high*digit
elif cur==1:
ans+=high*digit+low+1
else:
ans+=(high+1)*digit
low+=cur*digit#low的迭代方法更巧妙
cur=high%10
high=high//10
digit*=10
return ans
题44:数字序列中某一位的数字
这道题的思路还是有迹可循能想到的,详解见👉王先生的题解
class Solution:
def findNthDigit(self, n: int) -> int:
if n<10:
return n
n=n+1-10
for i in range(2,10):
base = i*9*10**(i-1)
if n<=base:
break
else:
n-=base
if n%i:
val=10**(i-1)+int(n/i)
return int(str(val)[n%i-1])
else:
val=10**(i-1)+int(n/i)-1
return int(str(val)[-1])
题45:把数组排成最小的数
判断整数a和b合并后谁更小,只需要比较str(a)+str(b)
和str(b)+str(a)
谁更小即可(得学fei)
不需要自己写一个sort,重写python里的sorted函数即可:令sorted函数中的key参数等于functools.cmp_to_key(my_compare)
即可
class Solution:
def minNumber(self, nums: List[int]) -> str:
def cmp(a,b):
if a==b:
return 0
x,y=str(a)+str(b),str(b)+str(a)
for i in range(len(x)):###由于x和y可能太大了,所以得用字符串比较
if x[i]>y[i]:
return 1
elif x[i]<y[i]:
return -1
return 0
nums=sorted(nums,key=functools.cmp_to_key(cmp))
nums=[str(i) for i in nums]
return ''.join(nums)