Java打开转盘锁leetcode

        你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' 。每个拨轮可以自由旋转:例如把 '9' 变为 '0','0' 变为 '9' 。每次旋转都只能旋转一个拨轮的一位数字。

        锁的初始数字为 '0000' ,一个代表四个拨轮的数字的字符串。

        列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。

        字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。

提示:

1 <= deadends.length <= 500
deadends[i].length == 4
target.length == 4
target 不在 deadends 之中
target 和 deadends[i] 仅由若干位数字组成

1、BFS

class Solution {
    public int openLock(String[] deadends, String target) {
        Set<String> visited = new HashSet<>();
        Set<String> dead = new HashSet<>();
        for(String s : deadends){
            dead.add(s);
        }

        Queue<String> queue = new LinkedList<>();
        queue.add("0000");
        int step = 0;
        visited.add("0000");

        while( !queue.isEmpty() ){
            int size = queue.size();
            for(int i = 0;i < size;i++){
                String temp = queue.poll();
                if(dead.contains(temp)){
                    continue;
                }
                if(temp.equals(target)){
                    return step;
                }
                //有四个数字,每个都有上下两个方向
                for(int j = 0;j < 4;j++){
                    String up = PlusOne(temp,j);
                    if( !visited.contains(up) ){
                        visited.add(up);
                        queue.add(up);
                    }
                    String down = MinusOne(temp,j);
                    if( !visited.contains(down) ){
                        visited.add(down);
                        queue.add(down);
                    }
                }
            }
            ++step;
        }
        return -1;
    }

    //上移一位
    public String PlusOne(String s,int j){
        char[] chs = s.toCharArray();
        if(chs[j] == '9'){
            chs[j] = '0';
        }else{
            chs[j] += 1;
        }
        return new String(chs);
    }

    //下移一位
    public String MinusOne(String s,int j){
        char[] chs = s.toCharArray();
        if(chs[j] == '0'){
            chs[j] = '9';
        }else{
            chs[j] -= 1;
        }
        return new String(chs);
    }
}

执行用时:75 ms, 在所有 Java 提交中击败了48.26%的用户

内存消耗:47.2 MB, 在所有 Java 提交中击败了26.83%的用户

2、双向BFS

class Solution {
    public int openLock(String[] deadends, String target) {
        
        Set<String> visited = new HashSet<>();
        
        Set<String> dead = new HashSet<>();
        for(String s : deadends){
            dead.add(s);
        }

        //用集合不用队列可以快速判断元素是否存在
        Set<String> q_start = new HashSet<>();
        Set<String> q_end = new HashSet<>();
        q_start.add("0000");
        q_end.add(target);
       
        int step = 0;

        while( !q_start.isEmpty() && !q_end.isEmpty()){
            //哈希集合在遍历过程中不能修改,用temp存储扩散结果
            Set<String> temp = new HashSet<>();

            //将q_start中的所有结点向周围扩散
            for(String cur : q_start){
                if(dead.contains(cur)){
                    continue; 
                }
                //如果结果Set中包含则返回
                if(q_end.contains(cur)){
                    return step;
                }
                visited.add(cur);

                //有四个数字,每个都有上下两个方向
                for(int j = 0;j < 4;j++){
                    String up = PlusOne(cur,j);
                    if( !visited.contains(up) ){
                        temp.add(up);
                    }
                    String down = MinusOne(cur,j);
                    if( !visited.contains(down) ){
                        temp.add(down);
                    }
                }
            }
            ++step;

            //交换q_start和q_end,temp即为q_start
            //下一轮就是while扩散q_end
            q_start = q_end;
            q_end = temp;
        }
        return -1;
    }

    //上移一位
    public String PlusOne(String s,int j){
        char[] chs = s.toCharArray();
        if(chs[j] == '9'){
            chs[j] = '0';
        }else{
            chs[j] += 1;
        }
        return new String(chs);
    }

    //下移一位
    public String MinusOne(String s,int j){
        char[] chs = s.toCharArray();
        if(chs[j] == '0'){
            chs[j] = '9';
        }else{
            chs[j] -= 1;
        }
        return new String(chs);
    }
}

执行用时:22 ms, 在所有 Java 提交中击败了94.46%的用户

内存消耗:41.7 MB, 在所有 Java 提交中击败了94.07%的用户

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Leetcode是一个在线的算法题库,Java是一种流行的编程语言。Leetcode上的题目可以用Java语言来解决。Leetcode上有大量的题目,覆盖了各种难度级别和算法类型,包括数组、字符串、链表、树、图、动态规划、排序、贪心、回溯等等。Java作为一种高级编程语言,可以快速并且简洁地解决Leetcode上的问题。此外,Java还有丰富的类库和框架,方便开发人员使用。如果你想使用Java来解决Leetcode的问题,可以在Leetcode上完成编码,然后在测试通过后,下载题目页面中的PDF文件,进行备份和归档,以便在以后需要的时候查看。 总而言之,Leetcode Java PDF可以让您用Java语言解决Leetcode上的问题,并将完成的代码用PDF文件格式化,以备将来参考。 ### 回答2: LeetCode是一个在线的编程题库,提供了2000多道算法题目,并且还提供了讨论和答案解释。其中,JavaLeetCode支持的编程语言之一,因此学习Java语言可以更好地完成LeetCode算法的练习。此外,LeetCode还提供了PDF文档,以便有需要的用户离线学习或分享给其他人。这些PDF文档包括Java编程语言的基础知识和LeetCode算法解析。如果想要成为一个出色的Java工程师或算法专家,深入学习LeetCode并掌握Java编程语言是非常重要的。因此,练习LeetCode算法和阅读编程语言的PDF文档对于提升编程技能和职业发展是非常有帮助的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值