思路
- 这种相当于找出一条路,其中路不包含
deadens
中的节点 - 找路的方式相当于每一位都进行翻转,相当于树的层序遍历,每一位都有两个节点,看能不能找到目的节点,并把路径长度记录下来
- 使用队列进行层序遍历
- 比较麻烦的是用数组模拟队列,以及数字翻转,数字翻转的思路参考用数组模拟循环队列。
环形队列: link. - 使用数组记录不可走的节点
层序遍历的模板
queue.pushback(start);
while (!queue.empty()){
for(i=0;i<queue.size();i++){
dequeue(queue,q);
visit(q);
//对q的子节点进行操作并进栈
queue.pushback(q.child());
}
result++;
}
代码
int openLock(char ** deadends, int deadendsSize, char * target){
int result =0;
int i,j,k;
int flag[10000];//记录不可走的节点
memset(flag,0,sizeof(int)*10000);
for(i=0;i<deadendsSize;i++){
flag[atoi(deadends[i])]=1;;
}
if(flag[atoi(target)]||flag[atoi("0000")])
return -1;
char queue[20000][5];//遍历使用的队列
int top = 0,front = -1;
strcpy(queue[top++],"0000");
front++;
while(front<top){
int len = top -front;
for(i=0;i<len;i++){
char temp[5];
strcpy(temp,queue[front]);
front++;
if(strcmp(temp,target)==0){
return result;
}
for(j=0;j<4;j++){
for(k=-1;k<2;k+=2){//0-9 0-1,思路就是环形队列中的push和pop
char t = (temp[j]-'0'+10+k)%10 + '0';
char temp_x[5];
strcpy(temp_x,temp);
temp_x[j] = t;
if(flag[atoi(temp_x)]==0){
flag[atoi(temp_x)]=1;
strcpy(queue[top++],temp_x);
}
}
}
}
result++;
}
result = -1;
return result;
}