力扣刷题笔记

# 1.DFS

约翰・霍普克洛夫特与罗伯特・塔扬在 1986 年共同获得计算机领域的最高奖:图灵奖。

深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.

下面通过题和联系去学会 DFS 方法。

下面是一般的 套路 ,不同情况不同处理。

void dfs(int step) // 可能还有其他辅助参数,具体情况,具体处理
{
	if(边界成立)
	{
		走到最深处
		。。。。。。
		return;
	}
	for(尝试每一种可能的状态)
	{
		if(如果这种状态可行){  // 剪枝
            把这种可能的状态标记,表示走过 
            继续下一步dfs(step+1)   // 状态转移
            把这种标记去除  // 回溯
		}
	}
}

一般像求组合,求排列,三层循环以上就可以使用回溯算法了。

和递归一样,步骤:

1. 找到终止条件。(出口)

2. 确定单层循环逻辑。

你可以找找这些算法去练练手:

  • 组合问题

    • 77. 组合
    • 216. 组合总数
    • 17. 电话号码的字幕总和
  • 分割问题

    • 131. 分割回文串
    • 93. 复原 IP 地址
  • 子集问题

    • 78. 子集
  • 棋盘问题

    • 51.N 皇后
    • 37. 数独
  • 其他问题

    • 周围岛屿周长

    // TODO...

    后续有做到会继续更新这里。。。

# 1. 电话号码的字符组合 难易程度: 🌟🌟🌟

题目描述:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = ""
输出:[]

实例 3:

输入:digits = "2"
输出:["a","b","c"]

tips:

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

# 解法 1:

可以看出当 index == str.length () 时就截止了

class Solution {
    char[][] letters = new char[][] {
        {}, // 0
        {}, // 1
        {'a','b','c'}, // 2
        {'d','e','f'}, // 3
        {'g','h','i'}, // 4
        {'j','k','l'}, // 5
        {'m','n','o'}, // 6
        {'p','q','r','s'}, // 7
        {'t','u','v'}, // 8
        {'w','x','y','z'} // 9
    };
    public List<String> letterCombinations(String digits) {
        List<String> res = new ArrayList<>();
        if(digits.length() == 0) return res;
        dfs(res, 0, new StringBuilder(), digits);
        return res;
    }
    void dfs(List<String> res,int index, StringBuilder sb, String str){
        // 截止条件
        if(index == str.length()){
            res.add(sb.toString());
            return ;
        }
        // 遍历一层的逻辑
        for(char c: letters[str.charAt(index) - '0']){
            sb.append(c);
            dfs(res, index+1, sb, str);
            sb.deleteCharAt(index);
        }
    }
}

# 2. 组合总和🌟🌟🌟

题目:

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

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

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

实例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
23 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7
仅有这两种组合。

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<>();
        dfs(candidates, target, new ArrayList(), ans);
        return ans;
    }
    void dfs(int[] candidates, int target,List<Integer> li, List<List<Integer>> ans ){
        // 截止条件
        if(target <= 0){ // 剪枝
            if(target == 0){
                List<Integer> tmp = new ArrayList<>(li);
                Collections.sort(tmp);
                if(!ans.contains(tmp)){
                    ans.add(tmp);
                }
            }          
            return;
        }
        // 其他候选
        for(int i = 0; i < candidates.length; i++){         
            li.add(candidates[i]);
            dfs(candidates, target-candidates[i], li, ans);
            li.remove(li.size() -1);
        }
    }
}

# 3. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例一:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例二:

输入:nums = [1]
输出:[[1]]

代码:

class Solution {
  
    public List<List<Integer>> permute(int[] nums) {
      
        List<List<Integer>> res  = new ArrayList();
        boolean[] pb = new boolean[nums.length]; 
        dfs(nums, pb, new ArrayList(), res);
        return res;
    }
    private void dfs(int[] nums,boolean[] pb, List<Integer> li,List<List<Integer>> res){
        if(li.size() == nums.length){
            res.add(new ArrayList(li)); // 一定要注意这里 new ArrayList
            return;
        }
        for(int i = 0; i < nums.length; i++){
            if(!pb[i]){
                li.add(nums[i]);
                pb[i] = true;
                dfs(nums, pb, li, res);
                li.remove(li.size() -1);
                pb[i] = false;
            }
        }
       
    }
}
更新于

请我喝[茶]~( ̄▽ ̄)~*

Jean 微信支付

微信支付

Jean 支付宝

支付宝

Jean 贝宝

贝宝