剑指offer--把数字翻译成字符串and把数组排成最小的数and数字序列中某一位的数字

题目:

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

示例 1:

输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"

思路:因为组合的之后数字的范围也要限定在26以内,即使前后两个数组合了也是要求10到25,才会多一种组合方式。这题用到动态规划,加了限定条件的青蛙跳台阶问题,每次组合可以自身组合,也可以和前面的数组合,只不过这个组合加了一个限制,具体看代码注释。

代码:

class Solution:
    def translateNum(self, num: int) -> int:
        #本题采用动态规划的方法,通过数组dp来记录第i位结尾的组合个数
        #     /* * 分两种情况:
        # *
        # * 1. 第i位数字 无法和前面的数组合,
        # *    比如 1245, 5 只能单独翻译,那么方法数和 124 是一样的
        # *    dp[i] = dp[i - 1]
        # *
        # * 2.第i位数字 可以和前面的数组合,
        # *   比如 1215, 5 可以选择 组合 和 不组合,最终结果为两种情况相加
        # *   a. 选择组合,15看成是整体,那么 dp[i] = dp[i - 2]
        # *   b. 不选择组合,5单独翻译,那么 dp[i] = dp[i - 1]
        # **/
        str_num=str(num)
        n=len(str_num)#求出来字符串的长度进行下面的动态规划
        dp=[1 for i in range(n+1)]#每一位的增加次数都是1
        #可以和前面的数组合的情况中,
        for i in range(1,n):
            if str_num[i-1]=="1" or (str_num[i-1]=="2" and str_num[i]<"6"):
                dp[i]=dp[i-1]+dp[i-2]
            else:
                dp[i]=dp[i-1]
        return dp[n-1]

题目:

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

示例 1:

输入: [10,2]
输出: "102"

思路:看起来是数组的排序问题,不过这里的前后调换顺序变为了字符串相加以后比较大小,然后判断ab应该放在前面还是后面。例如a+b<b+a(字符串的拼接),那说明b应该放在a的后面。本题只用冒泡排序来写,就是前后相邻的两个字符挨着比较,满足条件了就调换位置。

代码:if条件句中返回True的条件就是需要前后调换顺序

class Solution:
    def minNumber(self, nums: List[int]) -> str:
        #采用冒泡排序,效率低,只不过比较大小变为字符串相加的比较
        #比如a+b<b+a,就说明a<b,b应该放在后面
        #定义一个比较的函数
        def order(a,b):
            #a是比b大的,需要交换位置,把a放在后面
            if a+b>b+a:return True
            if a+b<b+a:return False
        #先把nums变为字符串,方便后面的比较
        nums=[str(i) for i in nums]
        #进行两两的比较,实现排序
        for i in range(len(nums)):
            for j in range(0,len(nums)-i-1):
                if order(nums[j],nums[j+1]):
                    nums[j],nums[j+1]=nums[j+1],nums[j]
        return "".join(nums)

 题目:

数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。

请写一个函数,求任意第n位对应的数字。

思路:如果我们可以找到当前第n位对应的十进制数,那我们就可以找到第n位表示的数字。

首先找规律,1位数总共占10个字符,2位数占90*2个字符,3位数占900*3个字符,假设i表示i位数,那所占字符数和i的关系位count=i*9*10**(i-1),如果给我们999,那可以用999-10-180=809,809/3就是三位数的十进制,加上100就是总共要找的十进制,如果有余数,那就通过余数re来找到十进制中的对应数字。

代码:

class Solution:
    def findNthDigit(self, n: int) -> int:
        if n<10:return n
        num=""
        yu=0
        count=10
        for i in range(1,10):
            if i!=1:count+=i*9*10**(i-1)
            if count<=n<count+(i+1)*9*10**i:
                re=n-count#计算出来在当前位剩了多少个数
                #此时的i是当前字符所在位数减一,例如999,此时i=2,999-1和2位数的字符个数就是三位数的字符
                #计算出来实际的十进制数是多少
                num=str(10**i+re//(i+1))
                yu=re%(i+1)
                return int(num[yu])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值