剑指offer 43-45题 python题解记录

题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)
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值