面試官問:你瞭解隊列和鏈表的區別嗎?
我:瞭解,blabla
面試官又問:你能自己實現隊列嗎?具體講講怎麼實現?
我當時說了用鏈表來實現隊列的存儲,並實現push和pop的操作,但回答的不具體,面試官有些搖頭。今天結合一道力扣題來實現隊列
題目
請定義一個隊列並實現函數 max_value 得到隊列裏的最大值,要求函數max_value、push_back 和 pop_front 的均攤時間複雜度都是O(1)。若隊列爲空,pop_front 和 max_value 需要返回 -1。
示例 1:
輸入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
輸出: [null,null,null,2,1,2]
解題思路:雙鏈表實現
max_value()
如果MAXQueueHead == MAXQueueTail 表示隊列中沒有元素,返回-1。在MAXQueue的頭指針的位置保存的就是此時隊列中的最大值,直接的取值就可以,時間複雜度是O(1)
push_back():
Queue數組正常的進行添加數據,Queue[QueueTail++] = value;
在進行入隊的時候,在MAXQueue中需要進行判斷,時間複雜度均攤下來也是O(1):比value小的值,一定會在value出棧前,先出棧,隊列中的最大值最少都是value,就沒有保存比value小的值的必要了,MAXQueueTail指向的索引,在數組MAXQueue中還沒被賦值,判斷的時候需要使用MAXQueueTail-1
MAXQueue[MAXQueueTail-1] < value
pop_front()
Queue中Head的值 與 MAXQueue中Head的值相等,則兩個數組中的head都要 ++ ,因爲最大值已經變了。不然,就是常規的Queue中的head++,時間複雜度是O(1)
解題代碼(java)
class MaxQueue {
List<Integer> list;
int listHead = 0;
int listTail = 0;
List<Integer> MAXlist;
int MAXlistHead = 0;
int MAXlistTail = 0;
public MaxQueue() {
list = new ArrayList<>();
MAXlist = new ArrayList<>();
}
public int max_value() {
if(MAXlistHead == MAXlistTail){
// 頭尾相等的時候,表示此時隊列爲空,沒有最大值
return -1;
}
return MAXlist.get(MAXlistHead);
}
public void push_back(int value) {
list.add(listTail++, value);
while(MAXlistHead != MAXlistTail && MAXlist.get(MAXlistTail-1) < value){
// MAXlistTail-1 因爲MAXlistTail處的值是0,還沒有被初始化
// 比value小的值,一定會在value出棧前,先出棧,
// 隊列中的最大值最少都是value,就沒有保存比value小的值的必要了
MAXlistTail--;
}
MAXlist.add(MAXlistTail++,value);
}
public int pop_front() {
if(listHead == listTail){
// 隊列爲空
return -1;
}
int res = list.get(listHead);
if(res == MAXlist.get(MAXlistHead)){
MAXlistHead++;
}
listHead++;
return res;
}
}