我是靠谱客的博主 柔弱菠萝,最近开发中收集的这篇文章主要介绍753. 破解保险箱 DFS+332.重新安排行程 回溯753. 破解保险箱332.重新安排行程 回溯,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

753. 破解保险箱

有一个需要密码才能打开的保险箱。密码是 n 位数, 密码的每一位是 k 位序列 0, 1, ..., k-1 中的一个 。

你可以随意输入密码,保险箱会自动记住最后 n 位输入,如果匹配,则能够打开保险箱。

举个例子,假设密码是 "345",你可以输入 "012345" 来打开它,只是你输入了 6 个字符.

请返回一个能打开保险箱的最短字符串。

示例1:

输入: n = 1, k = 2
输出: "01"
说明: "10"也可以打开保险箱。
 

示例2:

输入: n = 2, k = 2
输出: "00110"
说明: "01100", "10011", "11001" 也能打开保险箱。
 

提示:

n 的范围是 [1, 4]。
k 的范围是 [1, 10]。
k^n 最大可能为 4096。
 

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/cracking-the-safe
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

做题结果

失败,就觉得没思路,好像难以穷举所有结果,那如果走到错误的结果,怎么退回来?如何确定完成所有枚举结果?这几个问题没搞清楚。 

方法:DFS

1. 所有值都当做10进制看待(因为最多只有4位,不会超范围)

2. 必然存在回路,走一条边之后,一定有一种方法可以回到起点。所以解决了退回来的问题。一定会回来,不用退。

3. 回到起点后,可能存在另一个没走过的回路,继续走直到完成所有回路。解决了第二个问题,走完所有可以走的路就能枚举出所有结果。

class Solution {
        int k;
        boolean []existed;
        StringBuilder sb = new StringBuilder();
        int last;
        public String crackSafe(int n, int k) {//长度,数位最大+1
           last = (int) Math.pow(10,n-1);
           existed = new boolean[last*10];
           this.k = k;
           dfs(0);
           for(int i = 1; i < n; i++){
               sb.append("0");
           }

           return sb.toString();
        }

        private void dfs(int v){
            for(int i = 0; i < k; i++){
                int next = v*10+i;
                if(!existed[next]){
                    existed[next] = true;
                    dfs(next%last);
                    sb.append(i);
                }
            }
        }
        }

感想

别管题目多难,还是要敢写,不行就贪心或者暴力,试过了才不会有遗憾。 

332.重新安排行程 回溯

给你一份航线列表 tickets ,其中 tickets[i] = [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。

所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 开始。如果存在多种有效的行程,请你按字典排序返回最小的行程组合。

例如,行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前。
假定所有机票至少存在一种合理的行程。且所有的机票 必须都用一次 且 只能用一次。

示例 1:


输入:tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]
输出:["JFK","MUC","LHR","SFO","SJC"]
示例 2:


输入:tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
输出:["JFK","ATL","JFK","SFO","ATL","SFO"]
解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"] ,但是它字典排序更大更靠后。

提示:

1 <= tickets.length <= 300
tickets[i].length == 2
fromi.length == 3
toi.length == 3
fromi 和 toi 由大写英文字母组成
fromi != toi

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reconstruct-itinerary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

做题结果

成功,就是回溯,很简单,这题放现在应该算中等吧?

方法:DFS 暴搜

1. 建立图

2. 每个节点行程对应字典排序

3. 所有票都用完,得到可行结果

4. 每次乘飞机过程,消耗一张票(删除图的边,因为对于一个可行解来说用掉的票不能再用),如果不是可行结果,把票退回来(添加图的边)

5. 如果图中空了,没节点了,说明走完了,发现可行解,进行返回

6. 由于所有方案都是先走的字典序小的,所以遇到可行结果直接返回即可

7. 优化:如果从当前选择继续走可找到可行解,后续其他选择无需再走

class Solution {
    public List<String> findItinerary(List<List<String>> tickets) {
        Map<String,List<String>> graph = new HashMap<>();
        for(List<String> ticket:tickets){
            graph.putIfAbsent(ticket.get(0),new ArrayList<>());
            graph.get(ticket.get(0)).add(ticket.get(1));
        }

        for(String key:graph.keySet()){
            Collections.sort(graph.get(key));
        }

        List<String> curr = new ArrayList<>();
        curr.add("JFK");
        dfs(graph,"JFK",curr);
        return ans;
    }

    List<String> ans = new ArrayList<>();
    private boolean dfs(Map<String,List<String>> graph, String key,List<String> curr){
        if(graph.isEmpty()) {
            ans = new ArrayList<>(curr);
            return true;
        }
        if(graph.get(key)==null) return false;
        List<String> next = new ArrayList<>(graph.get(key));
        int n = next.size();
        for(int i = 0; i < n; i++){
            String nex = next.get(i);
            graph.get(key).remove(i);
            if(graph.get(key).isEmpty()) graph.remove(key);
            curr.add(nex);
            if(dfs(graph,nex,curr))return true;
            curr.remove(curr.size()-1);
            graph.putIfAbsent(key,new ArrayList<>());
            graph.get(key).add(i,nex);
        }
        return false;
    }

}

最后

以上就是柔弱菠萝为你收集整理的753. 破解保险箱 DFS+332.重新安排行程 回溯753. 破解保险箱332.重新安排行程 回溯的全部内容,希望文章能够帮你解决753. 破解保险箱 DFS+332.重新安排行程 回溯753. 破解保险箱332.重新安排行程 回溯所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(75)

评论列表共有 0 条评论

立即
投稿
返回
顶部