日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

752. Open the Lock

發(fā)布時(shí)間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 752. Open the Lock 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 1 題目理解
  • 2 BFS
  • 3 用int構(gòu)建狀態(tài)

1 題目理解

一個(gè)鐘表有4個(gè)槽,每個(gè)槽可以停在0-9,10個(gè)狀態(tài)。鐘表每個(gè)槽的輪子可以轉(zhuǎn),例如可以從0轉(zhuǎn)到9,也可以從0轉(zhuǎn)到1。
鐘表的起始狀態(tài)是"0000"。每個(gè)數(shù)字代表一個(gè)槽的狀態(tài)。
輸入:字符串?dāng)?shù)組deadends,表示不能死亡狀態(tài),進(jìn)入這個(gè)狀態(tài)鐘表就被鎖住了,不能動(dòng)了。輸入字符串target表示想要達(dá)到的狀態(tài)。
輸出:到達(dá)最終狀態(tài)的最少需要多少步。如果不能達(dá)到則為-1。
規(guī)則:每一步,鐘表只能轉(zhuǎn)動(dòng)一個(gè)槽,只能轉(zhuǎn)一下,
例子:
Input: deadends = [“0201”,“0101”,“0102”,“1212”,“2002”], target = “0202”
Output: 6
Explanation:
A sequence of valid moves would be “0000” -> “1000” -> “1100” -> “1200” -> “1201” -> “1202” -> “0202”.
Note that a sequence like “0000” -> “0001” -> “0002” -> “0102” -> “0202” would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end “0102”.

2 BFS

要求最短路徑長度,所以使用BFS。
在某一種狀態(tài)下,要先判斷這個(gè)狀態(tài)能不能動(dòng)。如果deadends包含target,則不能達(dá)到。

在正常狀態(tài)下,某一狀態(tài)的變化,可以變化其中一個(gè)槽,變化的動(dòng)作可以是加1,也可以是減1。變化之后進(jìn)入新的狀態(tài)。

class Solution {public int openLock(String[] deadends, String target) {Set<String> set = new HashSet<String>();for(String str : deadends){set.add(str);}String start = "0000";if(set.contains(target) || set.contains(start)) return -1;Queue<String> queue = new LinkedList<String>();queue.offer(start);set.add(start);int step = 0;while(!queue.isEmpty()){int size = queue.size();//System.out.println(queue);for(int r=0;r<size;r++){if(target.equals(queue.peek())){return step;}char[] current = queue.poll().toCharArray();for(int i=0;i<4;i++){char ch = current[i];int v = current[i]-48;current[i] = (char)(((v+1+10)%10)+48);String newState = new String(current);if(!set.contains(newState)){queue.offer(newState);set.add(newState);}current[i] = (char)(((v-1+10)%10)+48);String newState2 = new String(current);if(!set.contains(newState2)){queue.offer(newState2);set.add(newState2);}current[i] = ch;}}step++;}return -1;}}

時(shí)間復(fù)雜度:可以選擇的數(shù)據(jù)范圍n=10,狀態(tài)位數(shù)x=4,O(104?4?4)O(10^4*4*4)O(104?4?4)。最壞情況下有10410^4104種狀態(tài)。每個(gè)狀態(tài)可以有4*2=8種變化,所以是O(x)。枚舉后得到新的狀態(tài),構(gòu)建字符串,需要O(x)時(shí)間。所以最終結(jié)果是:O(nx?x?x)O(n^x*x*x)O(nx?x?x)

3 用int構(gòu)建狀態(tài)

因?yàn)槊總€(gè)位置的值在0-9之間,可以用4位二進(jìn)制表示,我們可以用int表示狀態(tài),這樣速度方面會(huì)更快。

class Solution {private final static int[] increments = new int[]{ 1, -1 };public int openLock(String[] deadends, String target) {int step = 0;Set<Integer> used = new HashSet<Integer>();String start = "0000";int startInt = 0;int targetInt = buildState(target);for(String deadend : deadends){used.add(buildState(deadend));}if(used.contains(startInt) || used.contains(targetInt)) return -1;used.add(startInt);Queue<Integer> queue = new LinkedList<Integer>();queue.offer(startInt);while(!queue.isEmpty()){int size =queue.size();for(int i=0;i<size;i++){int nodeInt = queue.poll();if(nodeInt==targetInt) return step;for(int increment : increments){for(int j =0;j<4;j++){int newNode = updateState(nodeInt,j,increment);if(!used.contains(newNode)){used.add(newNode);queue.offer(newNode);}}}}step++;}return -1;}private int updateState(int state, int d, int inc) {int mask = (1 << 4) - 1;int[] num = new int[]{state & mask,(state >> 4) & mask,(state >> 8) & mask,(state >> 12) & mask};int n = num[d];if (n == 0 && inc == -1) {num[d] = 9;} else if (n == 9 && inc == 1) {num[d] = 0;} else {num[d] += inc;}int res = 0;for (int i = 3; i >= 0; i--) {res <<= 4;res |= num[i];}return res;}private int buildState(String state) {char[] c = state.toCharArray();int res = 0;for (int i = 0; i < c.length; i++) {int d = c[i] - '0';res <<= 4;res |= d;}return res;} }

總結(jié)

以上是生活随笔為你收集整理的752. Open the Lock的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。