你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,‘0’ 变为 ‘9’ 。每次旋转都只能旋转一个拨轮的一位数字。
锁的初始数字为 ‘0000’ ,一个代表四个拨轮的数字的字符串。
列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。
字符串 target 代表可以解锁的数字,你需要给出最小的旋转次数,如果无论如何不能解锁,返回 -1。
分析:从0000开始解锁,对它每个位子进行拨动一共可以产生八种数字,1000,9000,0100,0900,0010,0090,0001,0009 可以视为第一次解锁操作,此时计数为1。然后继续对1000,9000,0100,0900,0010,0090,0001,0009中的每个1000,9000,0100,0900,0010,0090,0001,0009进行操作又会各自产生8个字符串,此时计数为2。 这类似于广度优先搜索遍历。
为了不产生重复字符串将每次得到的数字添加到死亡数组中。
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
public static int openLock(String [] demands, String target) {
HashSet dead = new HashSet<>(Arrays.asList(demands));//转化为哈希表
if( dead.contains("0000"))
return -1;
Queue queue = new LinkedList<>();
queue.add("0000");
int count = 0;
while(!queue.isEmpty()) {//队列中持续遍历直到为空
int size = queue.size(); //每次层BFS时的节点数,并在此层BFS结束时count+1
while(size > 0) {
String s = queue.remove();
System.out.println(s);
if(target.equals(s))
{
System.out.print("最后一次count为:"+count);
return count;
}
char [] c = s.toCharArray();
for(int i = 0; i < 4; i++) {//将每一位,进行加1 减 1 判断后放入队列中
int temp = c[i] - '0';
c[i] = (char)((temp + 9)%10 + '0'); //将位子数据减一
String stemp = String.valueOf(c);
if(!dead.contains(stemp)) { //如果dead集合不包含现 字符串,则存入dead集合与queue队列中
dead.add(stemp);
queue.add(stemp); //加入集合 防止重复
}
//做+1操作
c[i] = (char)((temp + 1)%10 + '0');
String sstemp = String.valueOf(c);
if(!dead.contains(sstemp)) {
dead.add(sstemp);
queue.add(sstemp);
}
//将更改后的位子恢复
c[i] = (char)( temp + '0');
}
size --;
}
count++ ;
}
return -1;
}
public static void main(String[] args) {
String [] s = {"0201","0101","0102","1212","2002"};
openLock(s,"0202");
}
}
标签:count,java,String,记录,dead,queue,add,拨轮,转盘
来源: https://blog.csdn.net/zkhong07/article/details/100107567