22.10.9 LC周赛 栈排序 + 矩阵移动(左上到右下)

编程入门 行业动态 更新时间:2024-10-08 23:00:44

22.10.9 LC周赛 栈排序 + <a href=https://www.elefans.com/category/jswz/34/1769510.html style=矩阵移动(左上到右下)"/>

22.10.9 LC周赛 栈排序 + 矩阵移动(左上到右下)

CSDN话题挑战赛第2期
参赛话题:算法题解

22.10.9 LC周赛 栈排序 + 矩阵移动

   这次周赛还是做出两道题,第三道有思路但不清晰,没有找到突破口,第四道很遗憾 DFS 给忘了,一紧张想不起来了,这次将把第三题 栈排序的方法 以及第四题 矩阵移动方法 给记录一下,再接再厉。

2434. 使用机器人打印字典序最小的字符串(栈 + 巧妙预处理排序)

题目链接:2434. 使用机器人打印字典序最小的字符串
题目大意:给你一个字符串 s 和一个机器人,机器人当前有一个空字符串 t 。执行以下操作之一,直到 s 和 t 都变成空字符串:

  • 删除字符串 s 的 第一个 字符,并将该字符给机器人。机器人把这个字符添加到 t 的尾部。
  • 删除字符串 t 的 最后一个 字符,并将该字符给机器人。机器人将该字符写到纸上。
    请你返回纸上能写出的字典序最小的字符串。

例如:

输入:s = "zza"
输出:"azz"
解释:用 p 表示写出来的字符串。
一开始,p="" ,s="zza" ,t="" 。
执行第一个操作三次,得到 p="" ,s="" ,t="zza" 。
执行第二个操作三次,得到 p="azz" ,s="" ,t="" 。输入:s = "bac"
输出:"abc"
解释:用 p 表示写出来的字符串。
执行第一个操作两次,得到 p="" ,s="c" ,t="ba" 。
执行第二个操作两次,得到 p="ab" ,s="c" ,t="" 。
执行第一个操作,得到 p="ab" ,s="" ,t="c" 。
执行第二个操作,得到 p="abc" ,s="" ,t="" 。输入:s = "bdda"
输出:"addb"
解释:用 p 表示写出来的字符串。
一开始,p="" ,s="bdda" ,t="" 。
执行第一个操作四次,得到 p="" ,s="" ,t="bdda" 。
执行第二个操作四次,得到 p="addb" ,s="" ,t="" 。
  • 解题思路: 输入 预处理结果 及输出结果 一下,预处理用于获取每一个字符段的头字母。

  • 时间复杂度:构造函数复杂度为 O ( N ) O(N) O(N) ,N为字符串长度

  • 空间复杂度:构造函数复杂度为 O ( N ) O(N) O(N)

class Solution:def robotWithString(self, s: str) -> str:# 经典贪心:求出栈序列的最小字典序。later = list(s)n = len(s)for i in range(n-2,-1,-1):later[i] = min(later[i],later[i+1])# print(s)ans,stack = list(),list()for i,ch in enumerate(s):while stack and stack[-1] <= later[i]:ans.append(stack.pop())stack.append(ch)ans += stack[::-1]return ''.join(ans)

62. 不同路径 (矩阵左上到右下)

题目链接:62. 不同路径
题目大意:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?

例如:

输入:m = 3, n = 7
输出:28
  • 解题思路:左上角 到 右下角 只走右和下 动态规划。
  • 时间复杂度: O ( M × N ) O(M×N) O(M×N),M N 分别为 矩阵的行和列
  • 空间复杂度: O ( M × N ) O(M×N) O(M×N)
class Solution:def uniquePaths(self, m: int, n: int) -> int:# 传统dp = [[1]*n] + [[1]+[0]*(n-1) for _ in range(m-1)]# print(dp))for i in range(1,m):for j in range(1,n):dp[i][j] = dp[i-1][j] + dp[i][j-1]return dp[m-1][n-1]

63. 不同路径 II(矩阵左上到右下)

题目链接:63. 不同路径 II
题目大意:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。

例如:

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
  • 解题思路:先预处理一下第一行和第一列 然后 在遍历其他位置 相对于 62. 不同路径 的区别是遇到障碍物后 continue。
  • 时间复杂度: O ( M × N ) O(M×N) O(M×N),M N 分别为 矩阵的行和列
  • 空间复杂度: O ( M × N ) O(M×N) O(M×N)
class Solution:def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:m,n = len(obstacleGrid),len(obstacleGrid[0])dp = [[0]*n for _ in range(m)]for i in range(n):# 左上角是障碍物 直接结束if obstacleGrid[0][i] == 1: breakdp[0][i] = 1for j in range(m):if obstacleGrid[j][0] == 1:breakdp[j][0] = 1for i in range(1,m):for j in range(1,n):if obstacleGrid[i][j] == 1: continuedp[i][j] = dp[i][j-1] + dp[i-1][j]return dp[m-1][n-1]

980. 不同路径 III( 矩阵上下左右从a到b走完除-1外所有格)

题目链接:980. 不同路径 III
题目大意:在二维网格 grid 上,有 4 种类型的方格:

  • 1 表示起始方格。且只有一个起始方格。
  • 2 表示结束方格,且只有一个结束方格。
  • 0 表示我们可以走过的空方格。
  • -1 表示我们无法跨越的障碍。
    返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目。
    每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格。

例如:

输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
输出:2
解释:我们有以下两条路径:
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)输入:[[1,0,0,0],[0,0,0,0],[0,0,0,2]]
输出:4
解释:我们有以下四条路径: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)输入:[[0,1],[2,0]]
输出:0
解释:没有一条路能完全穿过每一个空的方格一次。
请注意,起始和结束方格可以位于网格中的任意位置。
  • 解题思路:不用动态规划 回溯 老方法!
  • 时间复杂度: O ( 4 M × N ) O(4^{M×N}) O(4M×N) M和N分别为 grid 的行数和列数
  • 空间复杂度: O ( M × N ) O(M×N) O(M×N)
class Solution:def uniquePathsIII(self, grid: List[List[int]]) -> int:m,n = len(grid),len(grid[0])# start-(a,b) end-(c,d)a,b,c,d = 0,0,0,0step = 0for i,row in enumerate(grid):for j,val in enumerate(row):if val == 1: a,b = i,jif val == 2: c,d = i,jif val != -1: step += 1        self.ans = 0def dfs(x,y,todo):todo -= 1if x==c and y==d:if todo==0:self.ans += 1return # 已经走过 设置障碍物grid[x][y] = -1for nx,ny in [(x-1,y),(x+1,y),(x,y-1),(x,y+1)]:if 0<=nx<m and 0<=ny<n and grid[nx][ny] != -1:dfs(nx,ny,todo)grid[x][y] = 0dfs(a,b,step)return self.ans

64. 最小路径和 (矩阵路径扩展1)

题目链接:64. 最小路径和
题目大意:给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。

例如:

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。输入:grid = [[1,2,3],[4,5,6]]
输出:12
  • 解题思路:动态规划 不断比较右面和下面
  • 时间复杂度: O ( M × N ) O(M×N) O(M×N) M和N分别为 grid 的行数和列数
  • 空间复杂度: O ( M × N ) O(M×N) O(M×N)
class Solution:def minPathSum(self, grid: List[List[int]]) -> int:m,n = len(grid),len(grid[0])for i in range(1,m):grid[i][0] += grid[i-1][0]for j in range(1,n):grid[0][j] += grid[0][j-1]for i in range(1,m):for j in range(1,n):grid[i][j] += min(grid[i-1][j],grid[i][j-1])return grid[m-1][n-1]

2435. 矩阵中和能被 K 整除的路径 (矩阵路径扩展2)

题目链接:2435. 矩阵中和能被 K 整除的路径
题目大意:给你一个下标从 0 开始的 m x n 整数矩阵 grid 和一个整数 k 。你从起点 (0, 0) 出发,每一步只能往 下 或者往 右 ,你想要到达终点 (m - 1, n - 1) 。
请你返回路径和能被 k 整除的路径数目,由于答案可能很大,返回答案对 109 + 7 取余 的结果。

例如:

输入:grid = [[5,2,4],[3,0,5],[0,7,2]], k = 3
输出:2
解释:有两条路径满足路径上元素的和能被 k 整除。
第一条路径为上图中用红色标注的路径,和为 5 + 2 + 4 + 5 + 2 = 18 ,能被 3 整除。
第二条路径为上图中用蓝色标注的路径,和为 5 + 3 + 0 + 5 + 2 = 15 ,能被 3 整除。

输入:grid = [[0,0]], k = 5
输出:1
解释:红色标注的路径和为 0 + 0 = 0 ,能被 5 整除。

输入:grid = [[7,3,4,9],[2,3,6,2],[2,3,7,0]], k = 1
输出:10
解释:每个数字都能被 1 整除,所以每一条路径的和都能被 k 整除。
  • 解题思路:本周竞赛第四题 非常巧妙地做法啊! 由于需要遍历所有矩阵内容,由于未走到右下角,所以需要存放每一步的求余内容。
  • 时间复杂度: O ( M × N × K ) O(M×N×K) O(M×N×K) M和N分别为 grid 的行数和列数
  • 空间复杂度: O ( M × N × K ) O(M×N×K) O(M×N×K)
class Solution:def numberOfPaths(self, grid: List[List[int]], k: int) -> int:mod = 10**9+7m,n = len(grid),len(grid[0])dp = [[[0]*k for _ in range(n+1)] for _ in range(m+1)]dp[0][1][0] = 1for i,row in enumerate(grid):for j,x in enumerate(row):for v in range(k):z = (x+v)%kdp[i+1][j+1][z] = (dp[i+1][j+1][z]+dp[i+1][j][v]+dp[i][j+1][v])%modreturn dp[m][n][0]

总结

   努力 奋斗!争取 AC3道。

更多推荐

22.10.9 LC周赛 栈排序 + 矩阵移动(左上到右下)

本文发布于:2024-02-14 13:27:05,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1763637.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:矩阵   上到   LC   周赛

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!