打开转盘锁
评论区大神代码:
public int openLock(String[] deadends, String target) {Set<String> set = new HashSet<>(Arrays.asList(deadends));//开始遍历的字符串是"0000",相当于根节点String startStr = "0000";if (set.contains(startStr))return -1;//创建队列Queue<String> queue = new LinkedList<>();//记录访问过的节点Set<String> visited = new HashSet<>();queue.offer(startStr);visited.add(startStr);//树的层数int level = 0;while (!queue.isEmpty()) {//每层的子节点个数int size = queue.size();while (size-- > 0) {//每个节点的值String str = queue.poll();//对于每个节点中的4个数字分别进行加1和减1,相当于创建8个子节点,这八个子节点//可以类比二叉树的左右子节点for (int i = 0; i < 4; i++) {char ch = str.charAt(i);//strAdd表示加1的结果,strSub表示减1的结果String strAdd = str.substring(0, i) + (ch == '9' ? 0 : ch - '0' + 1) + str.substring(i + 1);String strSub = str.substring(0, i) + (ch == '0' ? 9 : ch - '0' - 1) + str.substring(i + 1);//如果找到直接返回if (str.equals(target))return level;//不能包含死亡数字也不能包含访问过的字符串if (!visited.contains(strAdd) && !set.contains(strAdd)) {queue.offer(strAdd);visited.add(strAdd);}if (!visited.contains(strSub) && !set.contains(strSub)) {queue.offer(strSub);visited.add(strSub);}}}//当前层访问完了,到下一层,层数要加1level++;}return -1;}作者:数据结构和算法
链接:https://leetcode-cn.com/leetbook/read/queue-stack/kj48j/?discussion=5WQchG
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我仿写了一遍,有个地方如果按我写的会超时,但是绝对是正确的,拿出来求网友解答,或者自己日后找到答案了就来解答:
class Solution {public int openLock(String[] deadends, String target) {Set<String> set = new HashSet<String>(Arrays.asList(deadends));String startStr = "0000";if(target.equals(startStr)){return 0;}if(set.contains(startStr)){return -1;}Queue<String> queue = new LinkedList<>();Set<String> visited = new HashSet<>();queue.offer(startStr);visited.add(startStr);int level = 0;while(!queue.isEmpty()){int size = queue.size();while(size-->0){String str = queue.poll();if(str.equals(target)){return level;} for(int i = 0;i<4;i++){char ch = str.charAt(i);String strAdd = str.substring(0,i)+(ch=='9'?0:ch-'0'+1)+str.substring(i+1);String strSub = str.substring(0,i)+(ch=='0'?9:ch-'0'-1)+str.substring(i+1);if(!visited.contains(strAdd)&&!set.contains(strAdd)){visited.add(strAdd);queue.offer(strAdd);}if(!visited.contains(strSub)&&!set.contains(strSub)){visited.add(strSub);queue.offer(strSub);}}}level++;}return -1;}
}
其中
String strAdd = str.substring(0,i)+(ch=='9'?0:ch-'0'+1)+str.substring(i+1);
String strSub = str.substring(0,i)+(ch=='0'?9:ch-'0'-1)+str.substring(i+1);
若写成我的想法就会超时:
String strAdd = str.substring(0,i)+(ch=='9'?'0':ch+1)+str.substring(i+1);
String strSub = str.substring(0,i)+(ch=='0'?'9':ch-1)+str.substring(i+1);
哪里效率变低了呢?