欧拉路径 与LC753. Cracking the Safe

这题也是醉了,需要知道欧拉路径这个知识点。
先说不用这个知识点怎么想。如果密码是六位,那五位组合是一个状态。每条边加前一个状态就是一个密码。每个状态加它所有的边就是所有密码了。这个问题就是如何最短的遍历完所有的边。
枚举所有密码是得不到正确答案的,要求是在枚举所有密码的时候同时复用前面n-1位。这个叫De Brunjin sequence。
我的参考文献是 leetcode解答和花花酱的视频 https://www.youtube.com/watch?v=kRdlLahVZDc
但是花花酱的视频没有讲欧拉路径,只讲了brute force的解法。
欧拉回路
连通图
每个点的入度和出度都相等。
每个点的入度和出度又都和别的相等。
这样的图会有欧拉回路。就有一个路径可以遍历所有的边和所有的状态。
从一个路径往下走,只有一种可能无路可走了,就是又回到了最初访问的那个边。
真的是很神奇,我也是看的一愣一愣的
差不多就是相当于绕地球绕了一圈又回到原地的感觉,然后再走下一圈。
还得细心体会。
看代码。

class Solution {
    public String crackSafe(int n, int k) {
        StringBuilder sb = new StringBuilder();
        String s = "";
        for (int i = 0; i < n - 1; i++)  s+= 0;
        Set edgeVisited = new HashSet<>();
        dfs(s, edgeVisited, k, sb);
        sb.append(s);
        return sb.toString();
    }
    private void dfs(String node, Set edgeVisited, int k, StringBuilder sb) { 
        for (int i = 0; i < k; i++) {
            String edge = node + i;
            if (edgeVisited.add(edge)) {
                dfs(edge.substring(1), edgeVisited, k, sb);
                sb.append(i);
            }
        }
    }
}

还是再做一下brute force的解法吧。神奇的是暴力解和 欧拉路径的解花的机器时间一样的。。。。
应该是因为虽然是暴力解,但早早退出

class Solution {
    public String crackSafe(int n, int k) {
        int total = (int) Math.pow(k, n);
        Set state = new HashSet<>();
        String s = "";
        for (int i = 0; i < n; i++) s += 0;
        StringBuilder sb = new StringBuilder(s);
        dfs(sb, state, total, n, k, s);
        return sb.toString();
    }
    private boolean dfs(StringBuilder sb, Set state, int total, int n, int k, String s) {
        if (!state.add(s)) return false;
        if (state.size() == total)  return true;
        for (int i = 0; i < k; i++) {
            sb.append(i);
            String sn = s.substring(1) + i;
            if (dfs(sb, state, total, n, k, sn)) return true;
            sb.deleteCharAt(sb.length() - 1);
        }
        state.remove(s);
        return false;
    }
}

你可能感兴趣的:(欧拉路径 与LC753. Cracking the Safe)