描述
有一種程式語言,只有以下五種命令,每種命令最多有兩個引數,請檢查給定的程式是否可能無限迴圈。
這些命令分別是:
label :宣告乙個標籤,引數是乙個字串,且每個標籤只宣告一次。
goto :跳轉到乙個標籤,並從標籤處開始按順序執行程式。
halt:停機,程式終止。
gotorand :隨機跳轉到兩個標籤中的乙個,並從標籤處開始按順序執行程式。
當程式執行完最後一句,且沒有跳轉時,程式終止。
設給定的程式的命令條數為 nn,1≤n≤1031≤n≤103。
所有標籤中只含有英文本元,且長度 mm,1≤m≤51≤m≤5。
輸出命令的字串長度 ll,1≤l≤201≤l≤20。
lintcode 領扣
樣例1
輸入:
label start
print "hello world!"
gotorand start end
print "good bye"
halt
label end
輸出:
true
說明
樣例中,每當程式執行到第三句 "gotorand start end" 後,都有可能回到第一句,從頭執行,也可能跳到最後一句。第四,五句將不會被執行。
我們可以將每一行命令抽象成乙個有向圖,然後將命令間的跳轉抽象成乙個有向邊,如果這個有向圖中有環的話,就認為可能會死迴圈。
有向圖判環的深度優先搜尋演算法:
如何判斷乙個有向圖是否有環,在他的深度優先搜尋樹上如果有乙個節點指回它的祖先節點,那麼這個有向圖是有環的。
時間複雜度
空間複雜度
public
class
solution
}return
dfs(0,
visitstate
,labelidx
,commands);}
/**
* idx的狀態
* 0 - 這個節點未被訪問過
* 1 - 這個節點被訪問過且在棧中
* 2 - 這個節點已被訪問過且已出棧
*/private
boolean
dfs(
intidx
,map
<
integer
,integer
>
visitstate
,map
<
string
,integer
>
labelidx
,list
<
string
>
commands
)// 程式中有環,可能會死迴圈 if(
visitstate
.containskey
(idx)&&
(int
)visitstate
.get
(idx)==
1)// visitstate = 2, 代表之後都不會死迴圈 if(
visitstate
.containskey
(idx)&&
(int
)visitstate
.get
(idx)==
2)// 將 idx 節點加入棧中
visitstate
.put
(idx,1
);boolean
flag
=false;if
(commands
.get
(idx
).charat(0
)=='h')if(
commands
.get
(idx
).charat(0
)=='g')
else
}else
visitstate
.put
(idx,2
);return
flag;}
}
更多題解參考:九章演算法
九章演算法 微軟面試題 公平索引
現在給你兩個長度均為n的整數陣列 a 和 b。當 a 0 a k 1 a k a n 1 b 0 b k 1 和 b k b n 1 四個和值大小相等時,稱索引k是乙個公平索引。也就是說,索引k 可以使得a,b 兩個陣列被分成兩個非空陣列,這四個子陣列的和值相等。例如,陣列a 4,1,0,3 b 2...
九章演算法 微軟面試題 加熱器
描述 冬天來啦!你的任務是設計出乙個具有固定加熱半徑的加熱器,使得所有房屋在這個冬天不至於太冷。現在你能夠獲知所有房屋和加熱器所處的位置,它們均分布在一條水平線中。你需要找出最小的加熱半徑使得所有房屋都處在至少乙個加熱器的加熱範圍內。所以,你的輸入將會是所有房屋和加熱器所處的位置,期望輸出為加熱器最...
九章演算法 微軟面試題 騎士撥號器
西洋棋中的騎士可以按下圖所示進行移動 每當它落在乙個鍵上 包括騎士的初始位置 都會呼出鍵所對應的數字,總共按下n位數字。你能用這種方式呼出多少個不同的號碼?因為答案可能很大,所以輸出答案模 10 9 7。1 n 5000 樣例 1 輸入 1 輸出 10 說明 答案可能是0,1,2,3,9,樣例 2 ...