[LeetCode]Lexicographical Numbers

题目描述:

LeetCode 386. Lexicographical Numbers

Given an integer n, return 1 - n in lexicographical order.

For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].

Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.

题目大意:

给定一个整数n,返回1到n的字典序排列。

例如,给定13,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9]。

请优化你的算法,使用更少的时间与空间。输入规模可能会达到5,000,000。

解题思路:

解法I 递归(Recursive)构造法

优先将数字乘10;如果数字末位<9,考虑将数字加1

递归式类似于二叉树的先根遍历

伪代码如下:

def solve(m):
    result.append(m)
    if m * 10 <= n: solve(m * 10)
    if m < n and m % 10 < 9: solve(m + 1)

Java代码:

public class Solution {
    private List<Integer> result;
    private int n;
    public List<Integer> lexicalOrder(int n) {
        this.result = new ArrayList<Integer>();
        this.n = n;
        solve(1);
        return result;
    }
    private void solve(int m) {
        result.add(m);
        if (m * 10 <= n) solve(m * 10);
        if (m < n && m % 10 < 9) solve(m + 1);
    }
}

由于递归的内存开销比较大,Python代码返回Memory Limit Exceeded

Python代码:

class Solution(object):
    def lexicalOrder(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        result = []
        def solve(m):
            result.append(m)
            if m * 10 <= n: solve(m * 10)
            if m < n and m % 10 < 9: solve(m + 1)
        solve(1)
        return result

解法II 迭代(Iterative)构造法

该解法实际上是解法I的迭代形式,可以类比二叉树先根遍历的迭代算法,需要用到栈(Stack)数据结构。

Python代码:

class Solution(object):
    def lexicalOrder(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        result = []
        stack = [1]
        while stack:
            y = stack.pop()
            result.append(y)
            if y < n and y % 10 < 9:
                stack.append(y + 1)
            if y * 10 <= n: 
                stack.append(y * 10)
        return result

下面的代码是迭代算法的另一种实现形式。

Python代码:

class Solution(object):
    def lexicalOrder(self, n):
        """
        :type n: int
        :rtype: List[int]
        """
        result = []
        stack = []
        x = 1
        while x <= n:
            stack.append(x)
            result.append(x)
            x *= 10
        while stack:
            y = stack.pop()
            if y % 10 == 9: continue
            y += 1
            while y <= n:
                stack.append(y)
                result.append(y)
                y *= 10
        return result

 

本文链接:http://bookshadow.com/weblog/2016/08/21/leetcode-lexicographical-numbers/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。

如果您喜欢这篇博文,欢迎您捐赠书影博客: ,查看支付宝二维码