• 算法通关18关 | 回溯模板如何解决排列和单词搜索问题


    1. 排列问题

    题目

    LeetCode46 给定一个没有重复数字的序列,返回其所有可能的全排列

    思路

    排列问题的思路同样使用与字母大小写全排列LeetCode784。

    元素在使用过一次的时候,在图中第二层的时候,还会再被使用,所以能用startIndex了,使用used[i]数组来标记已经选择的元素。过程如图示。

    回溯要注意横向和纵向问题,for是横向,递归是纵向

    终止条件:收集元素的数组大小和nums数组的大小一样大的时候,就找到了一个全排列

    代码

    1. /**
    2. * 排列问题,同样适用于字母大小写全排列
    3. */
    4. List> res = new ArrayList<>();
    5. LinkedList path = new LinkedList<>();
    6. boolean[] used;
    7. public List> permure(int[] nums){
    8. if (nums.length == 0){
    9. return res;
    10. }
    11. used = new boolean[nums.length];
    12. psermuteHelper(nums);
    13. return res;
    14. }
    15. private void psermuteHelper(int[] nums) {
    16. if (path.size() == nums.length){
    17. res.add(new ArrayList<>(path));
    18. return;
    19. }
    20. for (int i = 0; i < nums.length; i++) {
    21. //为true的时候代表再纵向被使用过,纵向第一条元素出来的时候,会转为false
    22. if (used[i]){
    23. continue;
    24. }
    25. used[i] = true;
    26. path.add(nums[i]);
    27. psermuteHelper(nums);
    28. path.removeLast();
    29. used[i] = false;
    30. }
    31. }

    2. 单词搜索

    题目

    LeetCode79 给定一个m x n 二维字符网格board和一个字符串单词。如果word存在在网格中,返回true,否则返回false。

    单词必须按照字母顺序,通过相邻单元格内的字母构成,其中"相邻 "单元格是那些水平相邻或垂直相邻的单元格,同一个单元格内的字母不允许重复使用。

    思路

    从上到下,从左到右,还是横向和纵向问题,每个坐标递归调用check(i,j,k)函数,i,j表示网格坐标,k表示word的第k个坐标,如果能搜索到返回true,否则返回false,check的终止条件有两种情况

    1. 如果i,j位置的字符和字符串位置k的字符不相等,则这条搜索路径返回失败。
    2. 如果搜索到了字符串的结尾,则找到了网格中的一条路径,这条路径上的字符正好可以组成字符串s。

    两层for循环分别纵向和横向遍历寻找第一个满足的字符,然后再递归寻找下一个

    代码

    1. public boolean exist(char[][] board,String word){
    2. char[] words = word.toCharArray();
    3. for (int i = 0; i < board.length; i++) {
    4. for (int j = 0; j < board[0].length; j++) {
    5. if (dfs(board,words,i,j,0)) return true;
    6. }
    7. }
    8. return false;
    9. }
    10. boolean dfs(char[][] board, char[] word, int i, int j, int k){
    11. //坐标越界
    12. if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[k]){
    13. return false;
    14. }
    15. //单词长度找完的时候
    16. if (k == word.length - 1){
    17. return true;
    18. }
    19. //转化为十进制0存储在ch中,十进制0对应的ASCII码中的字符即是NULL
    20. board[i][j] = '\0';
    21. boolean res = dfs(board,word,i + 1,j, k + 1) || dfs(board,word,i - 1,j, k + 1) ||
    22. dfs(board,word,i ,j + 1, k + 1)|| dfs(board,word,i ,j - 1, k + 1);
    23. board[i][j] = word[k];
    24. return res;
    25. }
  • 相关阅读:
    大端、小端模式
    通过使用css样式来做到2D动画的进度条加载的效果
    WebGL☀️Unity WebGL适配到各平台的教程
    AI问答-医疗:什么是“手术报台”
    2022美团CTF个人决赛WP
    多目标差分进化算法(Matlab代码实现)
    使用Feign远程调用快速入门
    数据仓库规范
    c#仿热血江湖
    python实现简单的神经网络,python实现神经网络算法
  • 原文地址:https://blog.csdn.net/m0_54138535/article/details/132840489