回溯法 深度优先 递归 回溯不一定借助递归

动态规划  游标 

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/

 

给定一个 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
 
 
 
 
 
 
 
 

 

posted @   papering  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用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
点击右上角即可分享
微信分享提示