LeetCode刷题实录Python篇(七)

174 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

1252. 奇数值单元格的数目

题目

给你一个 m x n 的矩阵,最开始的时候,每个单元格中的值都是 0。

另有一个二维索引数组 indices,indices[i] = [ri, ci] 指向矩阵中的某个位置,其中 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。

对 indices[i] 所指向的每个位置,应同时执行下述增量操作:

ri 行上的所有单元格,加 1 。 ci 列上的所有单元格,加 1 。 给你 m、n 和 indices 。请你在执行完所有 indices 指定的增量操作后,返回矩阵中 奇数值单元格 的数目。

示例 1:

输入:m = 2, n = 3, indices = [[0,1],[1,1]] 输出:6 解释:最开始的矩阵是 [[0,0,0],[0,0,0]]。 第一次增量操作后得到 [[1,2,1],[0,1,0]]。 最后的矩阵是 [[1,3,1],[1,3,1]],里面有 6 个奇数。 示例 2:

输入:m = 2, n = 2, indices = [[1,1],[0,0]] 输出:0 解释:最后的矩阵是 [[2,2],[2,2]],里面没有奇数。

提示:

1 <= m, n <= 50 1 <= indices.length <= 100 0 <= ri < m 0 <= ci < n

进阶:你可以设计一个时间复杂度为 O(n + m + indices.length) 且仅用 O(n + m) 额外空间的算法来解决此问题吗?

代码

class Solution:
    def oddCells(self, m: int, n: int, indices: List[List[int]]) -> int:
        # 方法1:用模拟的方式,但是这样太简单,并且复杂度较高
        # 方法2:记录每行增加次数和每列增加次数,遍历每个格子

        # 这里我将使用方法二
        row = [0] * m
        col = [0] * n
        for r, c in indices:
            row[r] += 1
            col[c] += 1

        # 这里还可以做些修改, 修改后时间和空间都有优化

        return sum((r+c) % 2 for r in row for c in col)

视频

www.bilibili.com/video/BV17a…

1260. 二维网格迁移

题目

给你一个 m 行 n 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。

每次「迁移」操作将会引发下述活动:

位于 grid[i][j] 的元素将会移动到 grid[i][j + 1]。 位于 grid[i][n - 1] 的元素将会移动到 grid[i + 1][0]。 位于 grid[m - 1][n - 1] 的元素将会移动到 grid[0][0]。 请你返回 k 次迁移操作后最终得到的 二维网格。

示例 1:

输入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 1 输出:[[9,1,2],[3,4,5],[6,7,8]] 示例 2:

输入:grid = [[3,8,1,9],[19,7,2,5],[4,6,11,10],[12,0,21,13]], k = 4 输出:[[12,0,21,13],[3,8,1,9],[19,7,2,5],[4,6,11,10]] 示例 3:

输入:grid = [[1,2,3],[4,5,6],[7,8,9]], k = 9 输出:[[1,2,3],[4,5,6],[7,8,9]]

提示:

m == grid.length n == grid[i].length 1 <= m <= 50 1 <= n <= 50 -1000 <= grid[i][j] <= 1000 0 <= k <= 100

代码

class Solution:
    def shiftGrid(self, grid: List[List[int]], k: int) -> List[List[int]]:
        # 所谓的移动其实是坐标的转换,这里类似于数据结构数组那一块讲的二维转一维,
        # 转成一维之后整体移动k位即可
        m, n = len(grid), len(grid[0])  # 行列长度
        ans = [[0] * n for _ in range(m)] # m行n列的0数组
        # 下面根据行列进行行优先的二维转一维
        for i in range(m):
            for j in range(n):
                idx = i * n + j # 这里验证一下,i=2,j=2时, idx = 2 * m + 2,1维中第2 * m + 2位
                # print(idx)
                idx += k # 加k位
                idx = idx % (m * n)  # 越界之后回到0,从头开始
                # print(idx, m, n)
                ans[idx // n][idx % n] = grid[i][j]  # 这里还是越界了

        return ans

视频 www.bilibili.com/video/BV1uT…

814. 二叉树剪枝

题目

给你二叉树的根结点 root ,此外树的每个结点的值要么是 0 ,要么是 1 。

返回移除了所有不包含 1 的子树的原二叉树。

节点 node 的子树为 node 本身加上所有 node 的后代。

示例 1: 在这里插入图片描述

输入:root = [1,null,0,0,1] 输出:[1,null,0,null,1] 解释: 只有红色节点满足条件“所有不包含 1 的子树”。 右图为返回的答案。 示例 2:

在这里插入图片描述

输入:root = [1,0,1,0,0,0,1] 输出:[1,null,1,null,1] 示例 3:

在这里插入图片描述

输入:root = [1,1,0,1,1,0,1,0] 输出:[1,1,0,1,1,null,1]

提示:

树中节点的数目在范围 [1, 200] 内 Node.val 为 0 或 1

代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pruneTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        # 深度优先搜索,如果左右子树均可删除或者当前结点为叶子结点则去除
        def cut(root)->bool:
            if root.left is not None:
                left = cut(root.left)
                if left:
                    root.left = None
            
            if root.right is not None:
                right = cut(root.right)
                if right:
                    root.right = None

            if root.val == 0 and root.left is None and root.right is None:
                # 叶子结点为0说明这个结点应该删除
                return True

            return False

        head = cut(root)
        if head:
            return None

        else:
            return root

视频 www.bilibili.com/video/BV1ag…