學妹睡醒之後聽了我的講解,頓時抓到重點。「哦,對耶,學生的順序不重要,重要的是三明治的順序。因為學生會自動重排到能拿三明治為止。」
「是呀,這種情境題目很有趣,可以用很多方式發散思維;但是有一類題目通常有標準答案,那就是用特定資料結構模擬其他資料結構。」這種題目也挺受某些面試官歡迎,我自己是不太喜歡啦。
「真的有這種題目嗎!」她臉上寫著「我解題少,別騙我」。
學妹以為我在說都市傳說嗎?哈哈。
我用queue的Tags過濾題目,在不到十筆的題目單裏很快找到了目標。「有啊,比如232. Implement Queue using Stacks就是要求用Stack模擬出Queue。」
「嗯?可是上面寫說有些語言可能沒有Stack耶?」學妹眨眨眼睛。
「嗯,對呀,畢竟語言開發者也是有他們的偏好的,如果沒有Stack,通常會找LinkedList替代。」
「我只用過ArrayList,不能用ArrayList嗎?」學妹問。
「可以啊,只是LinkedList在查詢首尾資料的效能會比ArrayList好,而Stack和Queue就是首尾資料的愛好者啊。」我慢慢說明原因。
ArrayList和Array的特徵就是資料儲存的位址是連續的,所以要找哪個資料其實就是直接找位址上的值;LinkedList因為是不連續的,所以要依賴鄰近成員之間的連結指引,因此要找在指定位置的值要從首尾開始依序找。
學妹對於ArrayList位址連續性存疑。「Array固定大小,所以一開始就能要求足夠空間。可是ArrayList不是可以增加長度嗎?怎麼會知道要多少空間?」
「哦,其實ArrayList一開始就會拿比較大一點的空間,但是如果真的不夠用,就會申請新天地,然後全家搬過去。所以最後還是在同個連續空間。」ArrayList的解決方式真是簡單粗暴,有點羨慕。「話說回來,這題就算使用LinkedList,也必須只能用和Stack相同行為的方法,否則會變得超簡單。」
因為Queue所有的方法LinkedList都有對應的方法啊。
class MyQueue() {
private val list = LinkedList<Int>()
fun push(x: Int) {
list.add(x)
}
fun pop(): Int {
return list.removeFirst()
}
fun peek(): Int {
return list.first()
}
fun empty(): Boolean {
return list.isEmpty()
}
}
「我先試試看Kotlin裡有沒有Stack,如果沒有,學姊再和我說LinkedList哪些方法能用。」學妹說著就加了宣告程式碼。
private val stack = Stack<Int>()
「哦,看起來沒有問題,那就佔照題目說的用兩個Stack來解題吧。」學妹開始認真思考。