题目
题目链接:
https://www.nowcoder.com/practice/e7cbabbf7e0a41ec98055ee5f3d33bbe
https://www.lintcode.com/problem/796
思路
Java代码
import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param vec string字符串ArrayList* @param tar string字符串* @return int整型*/public int open (ArrayList<String> vec, String tar) {//BFS 注意 当前状态,能得到到的下一个状态列表如何得到//比如0000的可以变化的下一个状态: 共4位,每一位取上一个值,下一个值// [9000, 1000, 0900, 0100, 0090, 0010, 0009, 0001]if ("0000".equals(tar)) return 0;Set<String> locked = new HashSet<>();for (String d : vec) {locked.add(d);if ("0000".equals(d)) return -1; //初始就被锁住了}Queue<String> q = new LinkedList<>();q.add("0000");Set<String> visited = new HashSet<>();visited.add("0000");int step = 0;while (!q.isEmpty()) {step++;int size = q.size();for (int i = 0; i < size; i++) {String status = q.poll();List<String> nexts = getNexts(status);//比如0000的nexts: [9000, 1000, 0900, 0100, 0090, 0010, 0009, 0001]for (String next : nexts) {if (visited.contains(next) || locked.contains(next)) continue;if (next.equals(tar)) return step;q.add(next);visited.add(next);}}}return -1;}//枚举status通过一次旋转得到的数字public List<String> getNexts(String status) {List<String> ans = new ArrayList<>();char[] arr = status.toCharArray();for (int i = 0; i < 4; i++) {char x = status.charAt(i);//上一个数char prev = x == '0' ? '9' : (char)(x - 1);arr[i] = prev;ans.add(new String(arr));//下一个数char succ = x == '9' ? '0' : (char)(x + 1);arr[i] = succ;ans.add(new String(arr));arr[i] = x;}return ans;}
}
Go代码
package main/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param vec string字符串一维数组* @param tar string字符串* @return int整型*/
func open(vec []string, tar string) int {//BFS 注意 当前状态,能得到到的下一个状态列表如何得到//比如0000的可以变化的下一个状态: 共4位,每一位取上一个值,下一个值// [9000, 1000, 0900, 0100, 0090, 0010, 0009, 0001]if tar == "0000" {return 0}locked := map[string]bool{}for _, d := range vec {locked[d] = trueif d == "0000" {return -1 //初始位置就被锁住了}}q := []string{}visited := map[string]bool{}step := 0q = append(q, "0000")for len(q) > 0 {step++size := len(q)qbak := []string{}for i := 0; i < size; i++ {status := q[i]nexts := getNexts(status)//比如0000的nexts: [9000, 1000, 0900, 0100, 0090, 0010, 0009, 0001]for _, next := range nexts {if next == tar {return step}_, ok1 := locked[next]_, ok2 := visited[next]if ok1 || ok2 {continue}qbak = append(qbak, next)visited[next] = true}}q = qbak}return -1}// 枚举status通过一次旋转得到的数字
func getNexts(status string) []string {ans := []string{}arr := make([]byte, 4)for i := 0; i < 4; i++ {arr[i] = status[i]}for i := 0; i < 4; i++ {x := arr[i]//上一个var prev byte = '9'if x != '0' {prev = x - 1}arr[i] = prevans = append(ans, string(arr))//下一个var succ byte = '0'if x != '9' {succ = x + 1}arr[i] = succans = append(ans, string(arr))arr[i] = x}return ans
}
PHP代码
<?php/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param vec string字符串一维数组 * @param tar string字符串 * @return int整型*/
function open( $vec , $tar )
{//BFS 注意 当前状态,能得到到的下一个状态列表如何得到//比如0000的可以变化的下一个状态: 共4位,每一位取上一个值,下一个值// [9000, 1000, 0900, 0100, 0090, 0010, 0009, 0001]if($tar=='0000') return 0;$locked =[];foreach ($vec as $d){if($d=='0000') return -1; //初始位置就被锁住了$locked[$d] = $d;}$q = [0=>'0000'];$visited = [];$step = 0;while (count($q) >0){$step++;$qbak = [];$size =count($q);for($i=0;$i<$size;$i++){$status = $q[$i];$nexts = getNexts($status);//比如0000的nexts: [9000, 1000, 0900, 0100, 0090, 0010, 0009, 0001]foreach ($nexts as $next){if(isset($locked[$next])) continue;if(isset($visited[$next])) continue;if($next==$tar) return $step;$qbak[count($qbak)] = $next;$visited[$next] = $next;}}$q =$qbak;}return -1;
}// 枚举status通过一次旋转得到的数字
function getNexts($status){$ans = [];$arr = [];for($i=0;$i<4;$i++){$arr[$i] = $status[$i];}for($i=0;$i<4;$i++){$x = $arr[$i];//上一个$prev='9';if($x!='0'){$prev = intval($x)-1;$x.='';}$arr[$i] = $prev;$str = '';for($j=0;$j<4;$j++){$str.=$arr[$j];}$ans[count($ans)] = $str;//下一个$succ = '0';if($x!='9'){$succ=intval($x)+1;$succ.='';}$str = '';$arr[$i] = $succ;for($j=0;$j<4;$j++){$str.=$arr[$j];}$ans[count($ans)] = $str;$arr[$i] = $x;}return $ans;
}