【LeetCode-面试经典150题-day19】

目录

39.组合总和

22.括号生成

79.单词搜索


39.组合总和

题意:

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。
【输入样例】candidates = 2,3,6,7, target = 7

【输出样例】\[2,2,3,7]
解题思路:

1、先对数组进行排序,排序之后可以更好的比较

2、定义二维数组res存储最终的结果

3、定义函数进行递归调用,函数接收的参数有(res数组,当前路径数组path,candidates,target,当前path的和sum,以及从第index个索引开始找)

  1. 递归终止条件:当sum == target,找到一组结果,添加到res中并return结束当前的调用;

  2. 否则,继续遍历,如果sum+当前值candidatesindex以及大于taget,则终止遍历,因为刚刚排序了,后面的值越来越大;如果不大于,则把condidatesindex添加到path中,继续向下遍历

  3. 回溯操作,遍历完要移除路径path的最后一个元素,以便继续寻找可能的组合。

java 复制代码
class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(candidates);
        //从第0个元素开始找,当前路径和为0
        searchPath(res,new ArrayList<>(),candidates,target,0,0);
        return res;
    }

    public void searchPath(List<List<Integer>> res, List<Integer> path,int[] candidates, int target,int sum, int index){
        //逮到了
        if(sum == target){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i=index;i<candidates.length;++i){
            if(sum + candidates[i] > target) break;//是直接跳出循环噢
            path.add(candidates[i]);
            searchPath(res,path,candidates,target,sum+candidates[i],i);//sum要加上,可以重复选,所以还是i
            path.remove(path.size()-1);//回溯回溯
        }
    }
}

时间: 击败了79.91%

内存: 击败了60.05%

22.括号生成

题意:

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的括号组合。
【输入样例】n=3

【输出样例】"((()))","(()())","(())()","()(())","()()()"
解题思路:

1、有效的括号要求是左括号的总数要小于等于右括号,才能够正确匹配。

2.、初始时,左括号的数量和右括号的数量都为n

3、当剩余的左括号数=右括号数时,下一位只能添加左括号,不然无法匹配

4、当剩余的左括号数<右括号数并且左括号数>0时,下一位可以添加左括号也可以添加右括号

5、递归结束的条件时剩余的左括号数=右括号数=0,没找到一组可能的序列,要进行回溯,删掉当前寻找序列的最后一位。ps:括号数量要记得加回去

java 复制代码
class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        if(n < 0){
            return res;
        }
        search(res,new StringBuffer(),n,n);
        return res;
    }

    public void search( List<String> res, StringBuffer str, int left, int right){
        if(left == 0 && right == 0){
            res.add(str.toString());
            return;
        }
        if(left == right){
            search(res,str.append("("),--left,right);
            //回溯,括号数量加回去
            str.deleteCharAt(str.length()-1);
            ++left;
        }else if(left < right){
            if(left > 0){
                search(res,str.append("("),--left,right);
                str.deleteCharAt(str.length()-1);
                ++left;
            }
            search(res,str.append(")"),left,--right);
            str.deleteCharAt(str.length()-1);   
            ++right;
            
        }
    }
}

时间: 击败了72.95%

内存: 击败了75.13%

79.单词搜索

题意:

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

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
【输入样例】board = \["A","B","C","E","S","F","C","S","A","D","E","E"], word = "ABCCED"

【输出样例】true
解题思路:

1、由于同一个单元格内的字母不允许重复使用,定义二维boolean数据存储哪一个坐标元素已经使用

2、先遍历整个二维数组,寻找可能的开始元素boardij

3、找到第一个单元格后,要上下左右寻找符合单词的第二个字母的单元格,没找到返回false,找到继续找第三、第四,同理,没找到要返回false,返回后,返回上一个符合要求的单元格(回溯),看其余三个方向是否有满足条件的

4、递归的终止条件是访问的单元格=单词字符串的长度(true),或者上文说的上下左右都不符合下一位(false)

本题解法参考:leetcode回溯算法经典例题------单词搜索

java 复制代码
class Solution {
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        boolean[][] use = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (board[i][j] == word.charAt(0)){
                    use[i][j] = true;
                    if (search(use,i, j, 1, word, board))
                        return true;
                    else use[i][j] = false;
                }
            }
        }
        return false;
    }
 
    public boolean search(boolean[][] use, int m, int n, int i, String word, char[][] board) {
        if (i == word.length()) return true;
        else {
            if (m > 0 && board[m - 1][n] == word.charAt(i)&& !use[m - 1][n] ) {
                use[m - 1][n] = true;
                if (search(use, m - 1, n, i + 1, word, board))
                    return true;
                else use[m - 1][n] = false;
            }
            if (m < board.length - 1&& board[m + 1][n] == word.charAt(i) && !use[m + 1][n] ) {
                use[m + 1][n] = true;
                if (search(use, m +1, n, i + 1, word, board))
                    return true;
                else use[m + 1][n] = false;
            }
            if (n < board[0].length - 1 && board[m][n+1] == word.charAt(i) && !use[m][n+1] ) {
                use[m][n+1] = true;
                if (search(use, m, n+1, i + 1, word, board))
                    return true;
                else use[m][n+1] = false;
            }
            if (n > 0 && board[m][n-1] == word.charAt(i) && !use[m][n-1] ) {
                use[m][n-1] = true;
                if (search(use, m, n-1, i + 1, word, board))
                    return true;
                else use[m][n-1] = false;
            }
            return false;
        }
    }
}

时间: 击败了95.20%

内存: 击败了96.67%

相关推荐
Dola_Zou5 小时前
工厂智能排产软件算法保护与按产线计费实战
算法·自动化·软件工程·软件加密
啦啦啦啦啦zzzz7 小时前
Logger的组装(c++20)
c++·算法·c++20
尾善爱看海8 小时前
前端算法与手写题集
前端·算法
程序员阿鹏8 小时前
为什么MySQL InnoDB选择B+树?
数据结构·数据库·b树·sql·mysql·算法·缓存
AI 思录9 小时前
Prompt 事故档案(八):日常表达被标为“待校准”,AI 的爹味语法从哪里来
大数据·人工智能·算法·prompt·用户体验·ai合规
月光船幽幽9 小时前
跨范式映射的稳定接口设计
人工智能·python·算法
2601_9657422210 小时前
全媒体运营与短视频代运营,两者有什么区别?
大数据·数据结构·人工智能·算法·ai·媒体
wordbaby11 小时前
混合检索:两全其美的艺术
人工智能·算法
彧azz12 小时前
数据结构:关于图的学习
c语言·数据结构·笔记·学习·算法
热心网友俣先生12 小时前
A题-药材的烘干问题-题意逐句翻译
算法·数学建模