leetcode-指剑offer-2021.08.02

  1. 剑指 Offer 04. 二维数组中的查找
    1. 矩阵中战斗力最弱的 K 行
  2. 剑指 Offer 14- I. 剪绳子
  3. 剑指 Offer 14- II. 剪绳子 II
  4. 剑指 Offer 13. 机器人的运动范围
  5. 剑指 Offer 12. 矩阵中的路径
  6. 剑指 Offer 32 - I. 从上到下打印二叉树
  7. 剑指 Offer 32 - II. 从上到下打印二叉树 II
  8. 剑指 Offer 32 - III. 从上到下打印二叉树 III
剑指 Offer 04. 二维数组中的查找

将二维数组看成一个二叉搜索树,根是左下角的点,左分支小,右分支大,中序遍历是递增的。因此每次对比节点和目标值的大小,如果小了就往右边去,列增加,如果大了就往左边去,行减少。

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

从右上角开始搜索也是可以的,但是当遇到输入为[] ,target=0时会报错,因为matrix[0]会报错index超了。

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        i = 0
        j = len(matrix[0])-1
        while j >= 0 and i < len(matrix):
            if matrix[i][j] > target:
                j -= 1
            elif matrix[i][j] < target:
                i += 1
            else:return True
        return False
1337. 矩阵中战斗力最弱的 K 行

每日一题

class Solution:
    def kWeakestRows(self, mat: List[List[int]], k: int) -> List[int]:
        m, n = len(mat), len(mat[0]) # m是行,n是列数
        power = list()
        for i in range(m):
            l, r, pos = 0, n - 1, -1
            while l <= r:
                mid = (l + r) // 2
                if mat[i][mid] == 0:
                    r = mid - 1
                else:
                    pos = mid
                    l = mid + 1
            power.append((pos + 1, i))


        heapq.heapify(power) # 将列表转换为堆
        ans = list()
        for i in range(k): 
            ans.append(heapq.heappop(power)[1]) #从堆中返回弹出最小item的第二个元素(就是前面存入的行)
        return ans

剑指 Offer 14- I. 剪绳子

n = 2, 1+1
n = 3, 1+2
n = 4, 2+2
n = 5, 3+2
n = 6, 3+3
n = 7, 3+4 = 3+2+2 先剪成长度为3的绳子,一直到<=4就剪成长度为2的
n = 8, 3+3+2

class Solution:
    def cuttingRope(self, n: int) -> int:
        if n <= 3:
            return n-1
        res = 1
        while n >= 2:
            if n<=4:
                return res*n
            n -= 3
            res*=3
剑指 Offer 14- II. 剪绳子 II

动态规划解法。

class Solution:
    def cuttingRope(self, n: int) -> int:
        if n <= 3:
            return n-1
        dp=[0 for _ in range(n+1)]
        dp[1] = 1
        dp[2] = 2
        dp[3] = 3
        for i in range(4, n+1):
            for j in range(i-1):
                dp[i] = max(dp[j]*dp[i-j], dp[i])
        return dp[n]%1000000007
剑指 Offer 13. 机器人的运动范围
class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        def dfs(i,j):
            summ = i//10 + i%10 + j//10+j%10
            if 0<=i<m and 0<=j<n and summ<= k and (i,j) not in visited: # 防止重复走
                visited.add((i,j))
                return 1+dfs(i+1,j)+dfs(i,j+1)
            else:return 0
        visited = set()
        return dfs(0,0)
剑指 Offer 12. 矩阵中的路径
class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m = len(board)
        n = len(board[0])
        visited=[[0 for _ in range(n)]for _ in range(m)]
        for i in range(m):
            for j in range(n):
                if board[i][j]==word[0]:
                    visited[i][j] = 1
                    if self.backtrace(i, j, visited,board, word[1:]):
                        return True
                    else:visited[i][j]=0
        return False
    def backtrace(self, i,j,visited,board,word):
        if len(word) == 0:
            return True
        for i0,j0 in [[i+1,j], [i-1,j], [i,j+1], [i,j-1]]:
            if 0 <= i0 < len(board) and 0 <= j0 < len(board[0]) and board[i0][j0] == word[0]:
                if visited[i0][j0]:
                    continue
                else:
                    visited[i0][j0]=1
                    if self.backtrace(i0, j0, visited,board, word[1:]):
                        return True
                    else:
                        visited[i0][j0]=0
        return False
剑指 Offer 32 - I. 从上到下打印二叉树

bfs广度优先搜索,按层从左往右搜索

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        ans = []
        q = collections.deque() # 双向队列,也可以直接用list
        q.append(root)
        while q: 
            node = q.popleft() # node=q.pop(0) 如果用list的话
            ans.append(node.val)
            if node.left:q.append(node.left)
            if node.right:q.append(node.right)
        return ans
剑指 Offer 32 - II. 从上到下打印二叉树 II
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        q = collections.deque()
        ans=[]
        tmp = []
        q.append(root)
        while q:
            tmp = []
            for _ in range(len(q)): # 多一层循环,因为这里要按层存入ans

                node = q.popleft()
                tmp.append(node.val)
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            ans.append(tmp)
        return ans
剑指 Offer 32 - III. 从上到下打印二叉树 III
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        q = collections.deque()
        ans=[]
        tmp = []
        q.append(root)
        count = 1
        while q:
            tmp = []
            for _ in range(len(q)): # 多一层循环,因为这里要按层存入ans
                node = q.popleft()
                tmp.append(node.val)
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            if count%2 == 0:
                tmp.reverse() # 偶数层反转一下该层元素
            ans.append(tmp)            
            count += 1
        return ans

也可以用deque在队头插入,实现反向

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        q = collections.deque()
        ans=[]
        tmp = []
        q.append(root)
        while q:
            tmp = collections.deque() #数据类型变成双向队列了
            for _ in range(len(q)): # 多一层循环,因为这里要按层存入ans
                node = q.popleft()
                if len(ans)%2: #偶数层
                    tmp.appendleft(node.val) # 在左边插入
                else:
                    tmp.append(node.val) #奇数层在右边,队尾插入
                if node.left: q.append(node.left)
                if node.right: q.append(node.right)
            ans.append(list(tmp))# tmp要转换成list,才能被加入ans             
        return ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值