1291. 顺次数

258 阅读2分钟

我们定义「顺次数」为:每一位上的数字都比前一位上的数字大 1 的整数。

请你返回由 [low, high] 范围内所有顺次数组成的 有序 列表(从小到大排序)。

题目链接: leetcode-cn.com/problems/se…

示例 1:

输出:low = 100, high = 300
输出:[123,234]

示例 2:

输出:low = 1000, high = 13000
输出:[1234,2345,3456,4567,5678,6789,12345]

提示:

10 <= low <= high <= 10^9

首先分析需求

先举几个顺次数的例子

两位数:[12,23,34,45,56,67,78,89]
三位数:[123,234,345,456,678,789]
四位数:[1234,2345,3456,4567,5678,6789]

这个例子一举是不是就发现了,这个数是有限制的。

对于不同的n位数集合,有10-n个顺次数

那这样一看,就有很多很多种不同的做法了。

解法一

选最好想的一种,把数组里的数拿出来,对于每个数转化成string类型,然后切割,一个个的去判断他是不是顺次数🐶🐶🐶🐶🐶🐶,当然这是超出内存限制的,算个半年都算不完10^9那么多个。

但秉着说到做到的原则,我肯定要给你写出来啊,电脑好的不妨拿这个代码去跑下,记得加几个打印,不然都不知道跑到哪了。

class Solution(object):
    def sequentialDigits(self, low, high):
        """
        :type low: int
        :type high: int
        :rtype: List[int]
        """
        res = []
        for i in range(low,high):
            a = [] 
            aa = -1
            for n in str(i):
                a.append(n)
                aa += 1
                if aa > 0:
                    b = int(a[aa]) - int(a[aa - 1])
                    if b==1:
                        continue
                    a = []
                    break
            if len(a) == len(str(i)):
                res.append(i)
        return res

解法二

那么正常人要怎么做呢,我们可以考虑直接把这8+7+6+5+4+3+2+1 = 36个数列出来,然后循环这个列表,看看在不在[low, high]里面

我们就有代码

res = []

list = [12,23,.......]

LHList = [low, high]

for i in LHList:
    if low <=i<= high: 
        res.append(i)

解法三

那么假如我们不想把这个顺次数列表列出来呢,有没有办法用代码写一个呢

诶那么就有了下面的这个代码

class Solution(object):
    def sequentialDigits(self, low, high):
        """
        :type low: int
        :type high: int
        :rtype: List[int]
        """
        res = []
        def backtrack(index, step, num):
  #index用来确定首位数或末位数,step 用来进行行调整首位数,当step = 0时index的作用是确定首位数,num是用来保存当前的数,num*10 + i用来获得下一个顺次数
            if num > high:                   
                return
            if low <= num <= high:
                res.append(num)
            for i in range(index, 10): 
                if i > index and step > 0:
                    return
                backtrack(i + 1, step + 1, num * 10 + i)
        backtrack(1, 0, 0)
        res.sort()
        return res

我们用一个递归去构造这个数,当他的后一位和前一位不匹配的时候退出。

解法四

我们真的要去构造这样的数吗,因为我们从一开始就看出来了它所有数都是从123456789这个数里截取出来。我们可不可以考虑像一开始想的根据low是个n位数和high是个n位数去筛选需要做判断的

于是就有代码

class Solution(object):
    def sequentialDigits(self, low, high):
        """
        :type low: int
        :type high: int
        :rtype: List[int]
        """
        a = '123456789'
        res = []
        lenLow = len(str(low))
        lenHigh = len(str(high))
        for n in range(lenLow,lenHigh+1):
            for i in range(10):
                if i + n < 10:
                    i = int(a[i:i+n])
                    if low <=i<= high:
                        res.append(i)
        return res

想像一下那种小朋友的玩具,就一个

image.png

⬆️⬆️⬆️⬆️⬆️⬆️⬆️这样的滑窗,去切割这个数字再拿出来和low和high比较