剑指Offer题解【Python版】【LintCode】

个人博客:枫之羽

《剑指Offer》

说明:题目顺序和LintCode中的顺序相同。

目录

9. Fizz Buzz 问题

366. 斐波纳契数列

204. 单例

212. 空格替换

365. 二进制中有多少个1

35. 翻转链表

159. 寻找旋转排序数组中的最小值

73. 前序遍历和中序遍历树构造二叉树

40. 用栈实现队列

38. 搜索二维矩阵 II

111. 爬楼梯

28. 搜索二维矩阵

160. 寻找旋转排序数组中的最小值 II

72. 中序遍历和后序遍历树构造二叉树

36. 翻转链表 II

373. 奇偶分割数组

372. Delete Node in a Linked List

174. 删除链表中倒数第n个节点

165. 合并两个排序链表

35. 翻转链表

245. 子树

371. 用递归打印数字

140. 快速幂


9. Fizz Buzz 问题

给你一个整数n. 从 1 到 n 按照下面的规则打印每个数:

  • 如果这个数被3整除,打印fizz.
  • 如果这个数被5整除,打印buzz.
  • 如果这个数能同时被35整除,打印fizz buzz.

样例

比如 n = 15, 返回一个字符串数组:

[
  "1", "2", "fizz",
  "4", "buzz", "fizz",
  "7", "8", "fizz",
  "buzz", "11", "fizz",
  "13", "14", "fizz buzz"
]

挑战

Can you do it with only one if statement?

class Solution:
    """
    @param n: An integer
    @return: A list of strings.
    """

    def fizzBuzz(self, n):
        # write your code here
        res = []
        for i in range(1, n + 1):
            if i % 15 == 0:
                res.append("fizz buzz")
            elif i % 3 == 0:
                res.append("fizz")
            elif i % 5 == 0:
                res.append("buzz")
            else:
                res.append(str(i))
        return res

366. 斐波纳契数列

查找斐波纳契数列中第 N 个数。

所谓的斐波纳契数列是指:

  • 前2个数是 0 和 1 。
  • 第 i 个数是第 i-1 个数和第i-2 个数的和。

斐波纳契数列的前10个数字是:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...

样例

给定 1,返回 0

给定 2,返回 1

class Solution:
    """
    @param n: an integer
    @return: an ineger f(n)
    """

    def fibonacci(self, n):
        # write your code here
        f, g = 0, 1
        for i in range(1, n):
            f, g = g, f + g
        return f

204. 单例

单例 是最为最常见的设计模式之一。对于任何时刻,如果某个类只存在且最多存在一个具体的实例,那么我们称这种设计模式为单例。例如,对于 class Mouse (不是动物的mouse哦),我们应将其设计为 singleton 模式。

你的任务是设计一个 getInstance 方法,对于给定的类,每次调用 getInstance时,都可得到同一个实例。

样例

在 Java 中:

A a = A.getInstance();
A b = A.getInstance();

a 应等于 b.

挑战

如果并发的调用 getInstance,你的程序也可以正确的执行么?

输入测试数据 (每行一个参数)

5种Python单例模式的实现方式

class Solution:
    # @return: The same instance of this class every time
    instance = None
    @classmethod
    def getInstance(cls):
        # write your code here
        if cls.instance is None:
            cls.instance = Solution()
        return cls.instance

212. 空格替换

设计一种方法,将一个字符串中的所有空格替换成 %20 。你可以假设该字符串有足够的空间来加入新的字符,且你得到的是“真实的”字符长度。

你的程序还需要返回被替换后的字符串的长度。

样例

对于字符串"Mr John Smith", 长度为 13

替换空格之后,参数中的字符串需要变为"Mr%20John%20Smith",并且把新长度 17 作为结果返回。

挑战

在原字符串(字符数组)中完成替换,不适用额外空间

注意事项

如果使用 Java 或 Python, 程序中请用字符数组表示字符串。

输入测试数据 (每行一个参数)

数组与字符串互相转化:

字符串转数组
str = '1,2,3'
arr = str.split(',')
数组转字符串
arr = ['a','b']
str = ','.join(arr)


arr = [1,2,3]

str = ','.join(str(i) for i in b)

class Solution:
    """
    @param: string: An array of Char
    @param: length: The true length of the string
    @return: The true length of new string
    """

    def replaceBlank(self, string, length):
        # write your code here
        if string is None:
            return length
        cnt = 0
        for ch in string:
            if ch.isspace():
                cnt += 1
        L = length + cnt * 2
        index = L - 1
        for i in range(length - 1, -1, -1):
            if string[i].isspace():
                string[index], string[index - 1], string[index - 2] = '0', '2', '%'
                index -= 3
            else:
                string[index] = string[i]
                index -= 1
        return L

365. 二进制中有多少个1

计算在一个 32 位的整数的二进制表示中有多少个 1.

样例

给定 32 (100000),返回 1

给定 5 (101),返回 2

给定 1023 (1111111111),返回 10

挑战

If the integer is n bits with m 1 bits. Can you do it in O(m) time?

1、位运算

class Solution:
    """
    @param: num: An integer
    @return: An integer
    """
    # 1208ms 复杂度O(n)
    def countOnes(self, num):
        # write your code here
        res = 0
        for i in range(32):
            res += num & 1
            num >>= 1
        return res

2、内置函数bin() 整数转化为二进制,转化后字符串会多了"0b",需要替换掉

bin(10)
Out[5]: '0b1010'
bin(-1)
Out[6]: '-0b1'

class Solution:
    """
    @param: num: An integer
    @return: An integer
    """
        # 788ms
    def countOnes(self, num):
        # write your code here
        twoStr = bin(num).replace('0b','')
        if twoStr[0] == '-':
            return 32 - twoStr.count('0')
        else:
            return twoStr.count('1')

35. 翻转链表

翻转一个链表

样例

给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null

挑战

在原地一次翻转完成

详细分析见:【剑指Offer】反转链表

"""
Definition of ListNode

class ListNode(object):

    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""


class Solution:
    """
    @param head: n
    @return: The new head of reversed linked list.
    """

    def reverse(self, head):
        # write your code here
        pre = None  # 当前节点的前一个节点
        next = None  # 当前节点的后一个节点
        while head is not None:
            next = head.next  # 存储下一个节点
            head.next = pre  # 反向
            pre = head  # 后移
            head = next  # 链表后移
        return pre  # 反转后的链表

159. 寻找旋转排序数组中的最小值

假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。

你需要找到其中最小的元素。

你可以假设数组中不存在重复的元素。

样例

给出[4,5,6,7,0,1,2]  返回 0

注意事项

You may assume no duplicate exists in the array.

分析:题目保证了两部分分别有序,要找的是最小的数,据此可以使用二分 O(logn)

class Solution:
    """
    @param nums: a rotated sorted array
    @return: the minimum number in the array
    """

    def findMin(self, nums):
        # write your code here
        # if nums is None:
        # return 0
        l, r = 0, len(nums) - 1
        mid = l
        while nums[l] > nums[r]:
            mid = (l + r) >> 1
            # print('mid = %d   %d' % (mid, nums[mid]))
            if nums[mid] > nums[r]:
                l = mid
            elif nums[mid] < nums[l]:
                r = mid
            if r - l == 1:
                # print('r=%d l=%d' % (r, l))
                mid = r  # 右边肯定比左边的小
                break
        return nums[mid]

73. 前序遍历和中序遍历树构造二叉树

根据前序遍历和中序遍历树构造二叉树.

样例

给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树:

  2
 / \
1   3

注意事项

你可以假设树中不存在相同数值的节点


"""
Definition of TreeNode:
"""


class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None


class Solution:
    """
    @param inorder: A list of integers that inorder traversal of a tree
    @param postorder: A list of integers that postorder traversal of a tree
    @return: Root of a tree
    """

    def buildTree(self, preorder, inorder):
        # write your code here
        if not inorder:
            return None
        root = TreeNode(preorder[0])
        rootpos = inorder.index(preorder[0])  # 使用index(x)获取list中的x的下标
        root.left = self.buildTree(preorder[1: rootpos + 1], inorder[: rootpos])
        root.right = self.buildTree(preorder[rootpos + 1:], inorder[rootpos + 1:])
        return root

    def printBinaTree(self, root):
        print(root.val, end=" ")
        if root.left:
            self.printBinaTree(root.left)
        if root.right:
            self.printBinaTree(root.right)

if __name__ == '__main__':
    inorder = [1, 2, 3]
    preorder = [2, 1, 3]
    sol = Solution()
    root = sol.buildTree(preorder, inorder)
    sol.printBinaTree(root)
    # print(ans)

 

40. 用栈实现队列

正如标题所述,你需要使用两个栈来实现队列的一些操作。

队列应支持push(element),pop() 和 top(),其中pop是弹出队列中的第一个(最前面的)元素。

pop和top方法都应该返回第一个元素的值。

样例

比如push(1), pop(), push(2), push(3), top(), pop(),你应该返回1,2和2

挑战

仅使用两个栈来实现它,不使用任何其他数据结构,push,pop 和 top的复杂度都应该是均摊O(1)的

# list.pop(obj=list[-1]) 默认为移除最后一个元素,list.pop(1)表示溢出索引为1的元素
class MyQueue:

    def __init__(self):
        # do intialization if necessary
        self.stack1 = [] #栈的操作
        self.stack2 = [] #辅助栈模拟队列

    """
    @param: element: An integer
    @return: nothing
    """
    def push(self, element):
        # write your code here
        self.stack1.append(element)

    # list.pop(obj=list[-1]) 默认为移除最后一个元素,list.pop(1)表示溢出索引为1的元素
    def adjust(self):
        if len(self.stack2) == 0:       # 辅助栈为空时,则将stack1的所有元素添加到stack2中,出栈时则是队头;非空时,直接出栈即可
            while len(self.stack1) > 0:
                self.stack2.append(self.stack1.pop())

    """
     @return: An integer
    """
    def pop(self):  #   出队
        self.adjust()
        return self.stack2.pop()

    """
    @return: An integer
    """
    def top(self):  #取队头元素
        # write your code here
        self.adjust()
        return self.stack2[len(self.stack2) - 1]

38. 搜索二维矩阵 II

写出一个高效的算法来搜索m×n矩阵中的值,返回这个值出现的次数。

这个矩阵具有以下特性:

  • 每行中的整数从左到右是排序的。
  • 每一列的整数从上到下是排序的。
  • 在每一行或每一列中没有重复的整数。

样例

考虑下列矩阵:

[

    [1, 3, 5, 7],

    [2, 4, 7, 8],

    [3, 5, 9, 10]

]

给出target = 3,返回 2

挑战

要求O(m+n) 时间复杂度和O(1) 额外空间

解法1:暴力O(mn)

class Solution:
    """
    @param matrix: A list of lists of integers
    @param target: An integer you want to search in matrix
    @return: An integer indicate the total occurrence of target in the given matrix
    """

    def searchMatrix(self, matrix, target):
        # write your code here
        res = 0
        for i in matrix:
            for j in i:
                print(i, j)
                if j == target:
                    res += 1
        return res


if __name__ == '__main__':
    matrix = [

        [1, 3, 5, 7],

        [2, 4, 7, 8],

        [3, 5, 9, 10]

    ]
    sol = Solution()
    ans = sol.searchMatrix(matrix, 3)
    print(ans)

解法2:O(m+n)

class Solution:
    """
    @param matrix: A list of lists of integers
    @param target: An integer you want to search in matrix
    @return: An integer indicate the total occurrence of target in the given matrix
    """

    def searchMatrix(self, matrix, target):
        # write your code here
        if matrix == [] or matrix[0] == []:
            return 0
        row, column = len(matrix), len(matrix[0])
        i, j, res = row - 1, 0, 0
        while i >= 0 and j < column:
            if matrix[i][j] == target:
                i, j, res = i - 1, j + 1, res + 1
            elif matrix[i][j] < target:
                j += 1
            elif matrix[i][j] > target:
                i -= 1
        return res

二分? 

111. 爬楼梯

假设你正在爬楼梯,需要n步你才能到达顶部。但每次你只能爬一步或者两步,你能有多少种不同的方法爬到楼顶部?

样例

比如n=3,1+1+1=1+2=2+1=3,共有3种不同的方法

返回 3

class Solution:
    """
    @param n: An integer
    @return: An integer
    """

    def climbStairs(self, n):
        # write your code here
        if not n: return 0
        f, g = 0, 1
        for i in range(n+1):
            f, g = g, f + g
        return f

28. 搜索二维矩阵

写出一个高效的算法来搜索 m × n矩阵中的值。

这个矩阵具有以下特性:

  • 每行中的整数从左到右是排序的。
  • 每行的第一个数大于上一行的最后一个整数。

样例

考虑下列矩阵:

[
  [1, 3, 5, 7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]

给出 target = 3,返回 true

挑战

O(log(n) + log(m)) 时间复杂度

输入测试数据 (每行一个参数)

解法1:暴力O(mn)

class Solution:
    """
    @param matrix: matrix, a list of lists of integers
    @param target: An integer
    @return: a boolean, indicate whether matrix contains target
    """

    def searchMatrix(self, matrix, target):
        # write your code here
        for i in matrix:
            for j in i:
                if j == target:
                    return True
        return False

解法二:O(m+n)  参考:38. 搜索二维矩阵 II

解法三:二分 O(n*logm)

class Solution:
    """
    @param matrix, a list of lists of integers
    @param target, an integer
    @return a boolean, indicate whether matrix contains target
    """

    def searchMatrix(self, matrix, target):
        # write your code here
        if matrix == [] or matrix[0] == []: return False
        for i in range(len(matrix)):
            if matrix[i][0] == target or matrix[i][-1] == target:
                return True
            elif target > matrix[i][0] and target < matrix[i][-1]:
                l, r = 0, len(matrix[i])-1
                while l <= r:
                    mid = (l + r) >> 1
                    if matrix[i][mid] == target:
                        return True
                    elif matrix[i][mid] > target:
                        r = mid-1
                    else:
                        l = mid+1
        return False

解法四:二分 O(logmn)

编译有问题。。  先放这儿  参考:lintcode :搜索二维矩阵

代码【不能通过】:

class Solution:
    """
    @param matrix: matrix, a list of lists of integers
    @param target: An integer
    @return: a boolean, indicate whether matrix contains target
    """

    def searchMatrix(self, matrix, target):
        # write your code here
        if matrix == [] or matrix[0] == []:
            return False
        row, column = len(matrix), len(matrix[0])
        l, r = 0, row * column - 1
        while l <= r:
            mid = (l + r) >> 1
            tmp = matrix[mid / column][mid % column]
            if tmp > target:
                l = mid
            elif tmp < target:
                r = mid
            else:
                return True
        return False

160. 寻找旋转排序数组中的最小值 II

假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2)。

你需要找到其中最小的元素。

数组中可能存在重复的元素。

样例

给出[4,4,5,6,7,0,1,2]  返回 0

注意事项

The array may contain duplicates.

分析:这一题与之前的条件多了可能数组中元素重复,需要多加两条语句。 具体见代码

class Solution:
    """
    @param nums: a rotated sorted array
    @return: the minimum number in the array
    """

    def findMin(self, nums):
        # write your code here
        if nums[0] 0:# [1,1,1,-1,1]
            r -= 1
        while l < r:
            mid = (l + r) >> 1
            # print('mid = %d   %d' % (mid, nums[mid]))
            if nums[mid] > nums[r]:
                l = mid
            elif nums[mid] <= nums[l]:
                r = mid
            if r - l == 1:
                # print('r=%d l=%d' % (r, l))
                if nums[l] < nums[r]:
                    mid = l
                else:
                    mid = r
                break
        return nums[mid]

72. 中序遍历和后序遍历树构造二叉树

根据中序遍历和后序遍历树构造二叉树

样例

给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2]

返回如下的树:

  2

 /  \

1    3

注意事项

你可以假设树中不存在相同数值的节点

输入测试数据 (每行一个参数)


"""
Definition of TreeNode:
"""
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None


class Solution:
    """
    @param inorder: A list of integers that inorder traversal of a tree
    @param postorder: A list of integers that postorder traversal of a tree
    @return: Root of a tree
    """

    def buildTree(self, inorder, postorder):
        # write your code here
        if not postorder:
            return None
        root = TreeNode(postorder[-1])
        rootpos = inorder.index(postorder[-1])
        # print(rootpos, root.val)
        root.left = self.buildTree(inorder[:rootpos], postorder[:rootpos])
        # print(rootpos, len(postorder), postorder[-1])
        root.right = self.buildTree(inorder[rootpos + 1:], postorder[rootpos:-1])
        return root

    def printBinaTree(self, root):
        print(root.val, end=" ")
        if root.left:
            self.printBinaTree(root.left)
        if root.right:
            self.printBinaTree(root.right)


if __name__ == '__main__':
    inorder = [1, 2, 3]
    postorder = [1, 3, 2]
    sol = Solution()
    root = sol.buildTree(inorder, postorder)
    sol.printBinaTree(root)

36. 翻转链表 II

翻转链表中第m个节点到第n个节点的部分

样例

给出链表1->2->3->4->5->null, m = 2 和n = 4,返回1->4->3->2->5->null

挑战

在原地一次翻转完成

注意事项

m,n满足1 ≤ m ≤ n ≤ 链表长度

 

 

373. 奇偶分割数组

分割一个整数数组,使得奇数在前偶数在后。

样例

给定 [1, 2, 3, 4],返回 [1, 3, 2, 4]

挑战

在原数组中完成,不使用额外空间。

分析:每次找到最左边的第一个偶数和最右边的第一个奇数交换位置 O(n)

class Solution:
    """
    @param: nums: an array of integers
    @return: nothing
    """
    def partitionArray(self, nums):
        # write your code here
        l, r = 0, len(nums) - 1
        while l < r:
            while l < r and nums[l] % 2 == 1:   l += 1
            while l < r and nums[r] % 2 == 0:   r -= 1
            if l < r:
                nums[l], nums[r] = nums[r], nums[l]
                l += 1
                r -= 1

372. Delete Node in a Linked List

给定一个单链表中的一个等待被删除的节点(非表头或表尾)。请在在O(1)时间复杂度删除该链表节点。

样例

Linked list is 1->2->3->4, and given node 3, delete the node in place 1->2->4

分析:链表的非表头表尾节点的删除。

"""
Definition of ListNode
class ListNode(object):

    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""


class Solution:
    """
    @param: node: the node in the list should be deletedt
    @return: nothing
    """
    def deleteNode(self, node):
        # write your code here
        node.val = node.next.val
        node.next = node.next.next


174. 删除链表中倒数第n个节点

给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。

样例

给出链表1->2->3->4->5->null和 n = 2.

删除倒数第二个节点之后,这个链表将变成1->2->3->5->null.

挑战

O(n)时间复杂度

注意事项

链表中的节点个数大于等于n

分析:双指针一次遍历实现。 cur,pre两个指针,题目指出节点个数>=n,所以删除的节点可能是首节点。

cur指针后移n个,若当前节点为空,那么说明删除的是首节点,直接返回head.next;否则cur和pre一起向后移动直到cur为空,最后pre到达了要删除节点的前一个节点,pre.next=pre.next.next删除倒数第n个节点。

"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""


class Solution:
    """
    @param head: The first node of linked list.
    @param n: An integer
    @return: The head of linked list.
    """

    def removeNthFromEnd(self, head, n):
        # write your code here
        cur, pre = head, head
        for i in range(n):
            cur = cur.next
        if cur is None:
            return head.next
        while cur.next is not None:
            cur = cur.next
            pre = pre.next
        pre.next = pre.next.next
        return head

165. 合并两个排序链表

将两个排序链表合并为一个新的排序链表

样例

给出 1->3->8->11->15->null2->null, 返回 1->2->3->8->11->15->null

"""
Definition of ListNode
class ListNode(object):
    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    """
    @param l1: ListNode l1 is the head of the linked list
    @param l2: ListNode l2 is the head of the linked list
    @return: ListNode head of linked list
    """
    def mergeTwoLists(self, l1, l2):
        # write your code here
        res = ListNode(0)
        tmp = res
        while l1 is not None and l2 is not None:
            if l1.val < l2.val:
                tmp.next, l1 = l1, l1.next
            else:
                tmp.next, l2 = l2, l2.next
            tmp = tmp.next
        tmp.next = l1 if l1 != None else l2
        return res.next

35. 翻转链表

翻转一个链表

样例

给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null

挑战

在原地一次翻转完成

"""
Definition of ListNode

class ListNode(object):

    def __init__(self, val, next=None):
        self.val = val
        self.next = next
"""

class Solution:
    """
    @param head: n
    @return: The new head of reversed linked list.
    """
    def reverse(self, head):
        # write your code here
        pre = None  # 当前节点的前一个节点
        next = None  # 当前节点的后一个节点
        while head is not None:
            next = head.next  # 存储下一个节点
            head.next = pre  # 反向
            pre = head  # 后移
            head = next  # 链表后移
        return pre  # 反转后的链表

245. 子树

有两个不同大小的二叉树: T1 有上百万的节点; T2 有好几百的节点。请设计一种算法,判定 T2 是否为 T1的子树。

样例

下面的例子中 T2 是 T1 的子树:

       1                3
      / \              / 
T1 = 2   3      T2 =  4
        /
       4

下面的例子中 T2 不是 T1 的子树:

       1               3
      / \               \
T1 = 2   3       T2 =    4
        /
       4

注意事项

若 T1 中存在从节点 n 开始的子树与 T2 相同,我们称 T2 是 T1 的子树。也就是说,如果在 T1 节点 n 处将树砍断,砍断的部分将与 T2 完全相同。

分析:常用递归,这里python可以利用pos = str.find(str2),pos!=-1表示str包含str2

递归:

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""

class Solution:
    """
    @param T1: The roots of binary tree T1.
    @param T2: The roots of binary tree T2.
    @return: True if T2 is a subtree of T1, or false.
    """

    def isIdentity(self, T1, T2):
        if T1 is None and T2 is None:
            return True
        if T1 != None and T2 != None and T1.val == T2.val:
            return self.isIdentity(T1.left, T2.left) and self.isIdentity(T1.right, T2.right)
        return False

    def isSubtree(self, T1, T2):
        # write your code here
        res = False
        if T2 is None:# 空节点是任意树的子树
            return True
        if T1 is None:
            return False
        if T1.val == T2.val:
            res = self.isIdentity(T1, T2)
        if res == False:
            res = self.isSubtree(T1.left, T2)
        if res == False:
            res = self.isSubtree(T1.right, T2)
        return res

str.find():

"""
Definition of TreeNode:
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left, self.right = None, None
"""

class Solution:
    """
    @param T1: The roots of binary tree T1.
    @param T2: The roots of binary tree T2.
    @return: True if T2 is a subtree of T1, or false.
    """

    def get(self, root, rt):
        if root is None:
            rt.append("#")
            return
        rt.append(str(root.val))
        self.get(root.left, rt)
        self.get(root.right, rt)

    def isSubtree(self, T1, T2):
        # write your code here
        rt = []
        self.get(T1, rt)
        t1 = ",".join(rt)

        rt = []
        self.get(T2, rt)
        t2 = ",".join(rt)
        return t1.find(t2) != -1

371. 用递归打印数字

用递归的方法找到从1到最大的N位整数。

样例

给出 N = 1, 返回[1,2,3,4,5,6,7,8,9].

给出 N = 2, 返回[1,2,3,4,5,6,7,8,9,10,11,...,99].

挑战

用递归完成,而非循环的方式。

注意事项

用下面这种方式去递归其实很容易:

recursion(i) {
    if i > largest number:
        return
    results.add(i)
    recursion(i + 1)
}

但是这种方式会耗费很多的递归空间,导致堆栈溢出。你能够用其他的方式来递归使得递归的深度最多只有 N 层么?

递归: 在自己IDE上是对的, 提交不通过,暂存!

class Solution:
    """
    @param n: An integer
    @return: An array storing 1 to the largest number with n digits.
    """
    res = []
    def print(self, i, n):
        if n >= 1:
            m = i * 10
            for j in range(i, m):
                self.res.append(j)
            self.print(m, n - 1)

    def numbersByRecursion(self, n):
        # write your code here
        self.print(1, n)
        return self.res

if __name__ == '__main__':
    sol = Solution()
    ans = sol.numbersByRecursion(2)
    print(ans)

非递归:O(n)

class Solution:
    """
    @param n: An integer
    @return: An array storing 1 to the largest number with n digits.
    """

    def numbersByRecursion(self, n):
        # write your code here
        res = []
        res = [i for i in range(1, pow(10, n))]
        return res

140. 快速幂

计算an % b,其中a,b和n都是32位的非负整数。

样例

例如 231 % 3 = 2

例如 1001000 % 1000 = 0

挑战

O(logn)

分析:快速幂公式, 需要注意n==0的情况, 特判或者返回值写成res%b

class Solution:
    """
    @param a: A 32bit integer
    @param b: A 32bit integer
    @param n: A 32bit integer
    @return: An integer
    """

    def fastPower(self, a, b, n):
        # write your code here
        if n == 0: return 1 % b
        res, a = 1, a % b
        while n > 0:
            if n % 2 == 1:
                res = res * a % b
            a = a * a % b
            n >>= 1
        return res


if __name__ == '__main__':
    sol = Solution()
    a, b, n = 109, 10000007, 1000001
    ans = sol.fastPower(a, b, n)
    print(ans)

 

你可能感兴趣的:(剑指Offer,题集,剑指offer)