回溯法 深度优先 递归 回溯不一定借助递归
动态规划 游标
55. 跳跃游戏 - 力扣(LeetCode) https://leetcode.cn/problems/jump-game/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import "log" func max(a, b int) int { if a > b { return a } return b } // [1] [0] func canJump(nums []int) bool { n := len(nums) - 1 var rightMost int = nums[0] for i := 0; i <= n; i++ { log.Println(rightMost, " " , i) if i > rightMost { return false } rightMost = max(rightMost, i+nums[i]) if rightMost >= n { return true } } return false } |
小结:
1、注意12题、13题问题的差异:12题要求路径的连贯性,中间路径不能中断,13题没有这样的要求。
https://leetcode-cn.com/problems/word-search/
https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/
剑指 Offer 12. 矩阵中的路径
给定一个 m x n
二维字符网格 board
和一个字符串单词 word
。如果 word
存在于网格中,返回 true
;否则,返回 false
。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 输出:true
示例 2:
输入:board = [["a","b"],["c","d"]], word = "abcd" 输出:false
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
board
和word
仅由大小写英文字母组成
注意:本题与主站 79 题相同:https://leetcode-cn.com/problems/word-search/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | func dfs(i, j, k int, board [][]byte, word string, used [][]int) bool { n := len(word) if k == n { return true } r := len(board) c := len(board[0]) if i < 0 || i >= r || j < 0 || j >= c { return false } if used[i][j] == 1 { return false } if board[i][j] != word[k] { return false } used[i][j] = 1 b := dfs(i+1, j, k+1, board, word, used) || dfs(i-1, j, k+1, board, word, used) || dfs(i, j+1, k+1, board, word, used) || dfs(i, j-1, k+1, board, word, used) return b } /* [["A","B","C","E"],["S","F","E","S"],["A","D","E","E"]] "ABCESEEEFS" */ func exist(board [][]byte, word string) bool { n := len(word) r := len(board) c := len(board[0]) if n > r*c { return false } used := func () [][]int { l := [][]int{} for i := 0; i < r; i++ { ll := []int{} for ii := 0; ii < c; ii++ { ll = append(ll, 0) } l = append(l, ll) } return l } for i := 0; i < r; i++ { for j := 0; j < c; j++ { if dfs(i, j, 0, board, word, used()) { return true } } } return false } |
在有多条路可以选择的时候,选错了无法回头。
提前使用了不该走的路。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | func dfs(i, j, k int, board [][]byte, word string, used ...[]int) bool { n := len(word) if k == n { return true } r := len(board) c := len(board[0]) if i < 0 || i >= r || j < 0 || j >= c { return false } if board[i][j] != word[k] { return false } for _, v := range used { a, b := v[0], v[1] if a == i && b == j { return false } } if dfs(i+1, j, k+1, board, word, append(used, []int{i, j})...) { return true } if dfs(i-1, j, k+1, board, word, append(used, []int{i, j})...) { return true } if dfs(i, j+1, k+1, board, word, append(used, []int{i, j})...) { return true } if dfs(i, j-1, k+1, board, word, append(used, []int{i, j})...) { return true } return false } /* [["A","B","C","E"],["S","F","E","S"],["A","D","E","E"]] "ABCESEEEFS" */ func exist(board [][]byte, word string) bool { n := len(word) r := len(board) c := len(board[0]) if n > r*c { return false } for i := 0; i < r; i++ { for j := 0; j < c; j++ { if dfs(i, j, 0, board, word) { return true } } } return false } |
回溯法 深度优先搜索 注意传参-走过的坐标
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | func exist(board [][]byte, word string) bool { n := len(word) r := len(board) c := len(board[0]) if n > r*c { return false } var dfs func (i, j, k int, used ...[]int) bool dfs = func (i, j, k int, used ...[]int) bool { n := len(word) if k == n { return true } r := len(board) c := len(board[0]) if i < 0 || i >= r || j < 0 || j >= c { return false } if board[i][j] != word[k] { return false } for _, v := range used { a, b := v[0], v[1] if a == i && b == j { return false } } if dfs(i+1, j, k+1, append(used, []int{i, j})...) { return true } if dfs(i-1, j, k+1, append(used, []int{i, j})...) { return true } if dfs(i, j+1, k+1, append(used, []int{i, j})...) { return true } if dfs(i, j-1, k+1, append(used, []int{i, j})...) { return true } return false } for i := 0; i < r; i++ { for j := 0; j < c; j++ { if dfs(i, j, 0) { return true } } } return false } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | func movingCount(m int, n int, k int) int { f := func (i int) int { return i/10 + i%10 } used := [][]int{} var dfs func (i, j int) int dfs = func (i, j int) int { if i < 0 || i >= m || j < 0 || j >= n { return 0 } for _, v := range used { a, b := v[0], v[1] if a == i && b == j { return 0 } } ok := func () bool { c := 0 if i == 100 { c++ } if j == 100 { c++ } c += f(i) + f(j) return c <= k }() if !ok { return 0 } used = append(used, []int{i, j}) return 1 + dfs(i-1, j) + dfs(i+1, j) + dfs(i, j-1) + dfs(i, j+1) } c := 0 for i := 0; i < m; i++ { for j := 0; j < n; j++ { v := dfs(i, j) if c < v { c = v } } } return c } |
https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
地上有一个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。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1 输出:3
示例 2:
输入:m = 3, n = 1, k = 0 输出:1
提示:
1 <= n,m <= 100
0 <= k <= 20
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
2021-04-24 从Android内存到图片缓存优化
2021-04-24 百度C++工程师的那些极限优化(内存篇)
2021-04-24 享元模式
2021-04-24 协同编辑冲突处理算法综述
2021-04-24 大型前端项目内存优化总结
2021-04-24 雪碧图
2021-04-24 CodeReviewComments