[LeetCode] 753. Cracking the Safe

参考轻风舞动 的博客,网址:https://www.cnblogs.com/lightwindy/p/9847632.html

package algorithm;

import java.util.HashSet;
import java.util.Set;

/*
 *

[LeetCode] 753. Cracking the Safe 破解密码

You can keep inputting the password, the password will automatically be matched against the last n digits entered.

For example, assuming the password is "345", I can open it when I type "012345", but I enter a total of 6 digits.

Please return any string of minimum length that is guaranteed to open the box after the entire string is inputted.

Example 1:

Input: n = 1, k = 2
Output: "01"
Note: "10" will be accepted too.
Example 2:

Input: n = 2, k = 2
Output: "00110"
Note: "01100", "10011", "11001" will be accepted too. 
Note:

n will be in the range [1, 4].
k will be in the range [1, 10].
k^n will be at most 4096.

连续输入一串密码字符,每次输入一个会按最后一个字符开始匹配。给定密码长度为n,数字个数为k,k的值为0到k-1,用[0, k-1]的数字组成一个密码,使得这个密码一定能打开盒子,返回长度最短的一个密码。

思路:如果保证一定能打开箱子,输入的字符串要能覆盖所有的长度为n的字符串。其实是找到所有由[0, k-1]的数字组成的长度为n的组合,总共有k^n个组合。

解法:DFS

* */
public class CrackTheSafe {

        public String crackSafe(int n, int k) {
            StringBuilder sb = new StringBuilder();
            int total = (int) (Math.pow(k, n));  //此为k的n次方
            for (int i = 0; i < n; i++) sb.append('0');
     
            Set<String> visited = new HashSet<>();
            visited.add(sb.toString());
     
            dfs(sb, total, visited, n, k);
     
            return sb.toString();
        }
     
        private boolean dfs(StringBuilder sb, int goal, Set<String> visited, int n, int k) {
            if (visited.size() == goal) //当该字符串,包含n的所有的组合时,如n=2,k=2,包含4种,00,01,11,10时
                return true;
            String prev = sb.substring(sb.length() - n + 1, sb.length()); //前缀为除最后一个字符外,前面的前缀
            for (int i = 0; i < k; i++) {
                String next = prev + i;//添加最后一个字符
                if (!visited.contains(next)) { //不包含,则说明新的值
                    visited.add(next);
                    sb.append(i);
                    if (dfs(sb, goal, visited, n, k)) //符合条件,都包含
                        return true;
                    else {
                        visited.remove(next); //不包含  回退,继续探索下一个字符
                        sb.delete(sb.length() - 1, sb.length());
                    }
                }
            }
            return false;
        }
     
    
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String result=new CrackTheSafe().crackSafe(2,2);
        System.out.println("result="+result);
        //String ss="ab";
        //String hh=ss.substring(1, 2);
        //System.out.println(hh);
    }

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值