剑指 Offer 03. 数组中重复的数字

题目

找出数组中重复的数字。

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。


image.png

答案

class Solution(object):
    def findRepeatNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i, num in enumerate(nums):
            while nums[i] != i:
                m = nums[i]
                if nums[m] == m:
                    return m
                else:
                    nums[i] = nums[m]
                    nums[m] = m
        return -1

解析

2022-04-13 164128.jpg

剑指 Offer 04. 二维数组中的查找

题目

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

1438686872.png

答案

class Solution(object):
    def findNumberIn2DArray(self, matrix, target):
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if target == matrix[i][j]:
                return True
        return False

def findNumberIn2DArray(matrix, target):
    i, j = len(matrix) - 1, 0
    while i >= 0 and j < len(matrix[0]):
        if target > matrix[i][j]:
            j += 1
        elif target < matrix[i][j]:
            i -= 1
        else:
            return True
    return False

解析

image.png

剑指 Offer 05.替换空格

题目

请实现一个函数,把字符串s中的每个空格替换成“%20“。

image.png

答案

Python中字符串为不可变类型,因此不存在空间复杂度 O(1) 的解法

class Solution(object):
    def replaceSpace(self, s):
        """
        :type s: str
        :rtype: str
        """
        return s.replace(" ", "%20")

剑指 Offer 06. 从尾到头打印链表

题目

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

image.png

答案

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def reversePrint(self, head):
        stack = []
        while head:
            stack.append(head.val)
            head = head.next
        return stack[::-1]

解析

这道题使用了栈这种数据结构,我们先将链表中的元素从头到尾依次入栈,在代码中表示就是stack.append(head.val)。

然后将栈中的元素依次出栈,在Python中我们只需要使用反转链表即可stack[::-1]。

g

剑指 Offer 07. 重建二叉树

题目

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
限制:
0 <= 节点个数 <= 5000


请输入图片描述


实例一:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

实例二:
Input: preorder = [-1], inorder = [-1]
Output: [-1]

答案

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        index = {}
        for i, val in enumerate(inorder):
            index.setdefault(val, i)  

        def recur(rootInd, leftInd, rightInd):
            if leftInd > rightInd: 
                return None
            rootVal = preorder[rootInd]
            inRootInd = index[rootVal]
            root = TreeNode(rootVal)
            root.left = recur(rootInd+1, leftInd, inRootInd-1)
            root.right = recur(rootInd + (inRootInd-leftInd) + 1, inRootInd+1, rightInd)
            return root
        return recur(0, 0, len(inorder)-1)

解析

image.png

剑指 Offer 09. 用两个栈实现队列

题目

用两个栈实现队列。

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTaildeleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )


image.png

答案

class CQueue(object):
    def __init__(self):
        self.S_in = []
        self.S_out = []
    def appendTail(self, value):
        """
        :type value: int
        :rtype: None
        """
        self.S_in.append(value)
    def deleteHead(self):
        """
        :rtype: int
        """
        if self.S_out == []:
            while self.S_in != []:
                self.S_out.append(self.S_in.pop())
        if self.S_out != []:
            return self.S_out.pop()
        else:
            return -1

解析

image.png

剑指 Offer 10. 斐波那契数列

题目

找出数组中重复的数字。

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:

F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

答案

class Solution:
    def fib(self, n: int) -> int:
        x, y = 0, 1
        while n != 0:
            y = x + y
            x = y - x
            n -= 1
        return x % 1000000007

解析

381650526873_.pic.jpg

剑指 Offer 11. 旋转数组的最小数字

题目

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一次旋转,该数组的最小值为 1。

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

image.png

答案

class Solution:
    def minArray(self, numbers: List[int]) -> int:
        i, j = 0, len(numbers)-1
        while i < j:
            m = (i + j) // 2
            if numbers[m] > numbers[j]:
                i = m + 1
            elif numbers[m] < numbers[j]:
                j = m
            else:
                j -= 1
        return numbers[j]

解析

扫描全能王

剑指 Offer 12. 矩阵中的路径

题目

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

word2

答案

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m, n = len(board), len(board[0])
        visited = [[False] * n for _ in range(m)]
        def bfs(i, j, k):
            if k == len(word):
                return True
            if i < 0 or i >= m:
                return False
            if j < 0 or j >= n:
                return False
            if visited[i][j]:
                return False
            if word[k] != board[i][j]:
                return False
            visited[i][j] = True
            res = bfs(i+1, j, k+1) or bfs(i-1, j, k+1) or bfs(i, j+1, k+1) or bfs(i, j-1, k+1)
            visited[i][j] = False
            return res
        for i in range(m):
            for j in range(n):
                if bfs(i, j, 0):
                    return True
        return False

解析

iShot2022-04-26_20.40.37

剑指 Offer 13. 机器人的运动范围

题目

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

image-20220426224414433

答案

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        def sum(i, j):
            res = 0
            while i:
                res += i%10
                i //= 10
            while j:
                res += j%10
                j //= 10
            return res
        visited = set()
        def dfs(i, j):
            if i >= m or j >= n or sum(i, j) > k or (i, j) in visited:
                return 0
            visited.add((i, j))
            return 1 + dfs(i+1, j) + dfs(i, j+1)

        return dfs(0, 0)

解析

image-20220426213128962

最后修改:2022 年 04 月 26 日
如果觉得我的文章对你有用,请随意赞赏