携手创作,共同成长!这是我参与「掘金日新计划 · 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)
视频
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