1. 程式人生 > >【Java】 劍指offer(59-2) 佇列的最大值 《劍指Offer》Java實現合集 《劍指Offer》Java實現合集

【Java】 劍指offer(59-2) 佇列的最大值 《劍指Offer》Java實現合集 《劍指Offer》Java實現合集

 

本文參考自《劍指offer》一書,程式碼採用Java語言。

更多:《劍指Offer》Java實現合集  

題目

  請定義一個佇列並實現函式max得到佇列裡的最大值,要求函式max、push_back和pop_front的時間複雜度都是O(1)。

思路

  與滑動視窗的最大值一題相似,利用一個雙端佇列來儲存當前佇列裡的最大值以及之後可能的最大值。

  在定義題目要求功能的佇列時,除了定義一個佇列data儲存數值,還需額外用一個佇列maxmium儲存可能的最大值;此外,還要定義一個數據結構,用於存放資料以及當前的index值,用於刪除操作時確定是否刪除maxmium中最大值。

  具體實現見程式碼,程式碼進行了一些測試,應該沒有什麼問題。

 

測試算例 

  尾部插入不同大小數字,刪除頭部數字。插入刪除同時獲取最大值。

Java程式碼

import java.util.ArrayDeque;

//題目:請定義一個佇列並實現函式max得到佇列裡的最大值,要求函式max、
//push_back和pop_front的時間複雜度都是O(1)。

public class QueueWithMax {
	private ArrayDeque<InternalData>  data = new ArrayDeque<InternalData>();
	private ArrayDeque<InternalData> maximum = new ArrayDeque<InternalData>();
	private class InternalData{
		int number;
		int index;
		public InternalData(int number,int index) {
			this.number=number;
			this.index=index;
		}
	}
	private int curIndex;
	
	public void push_back(int number) {
		InternalData curData = new InternalData(number,curIndex);
		data.addLast(curData);
		
		while(!maximum.isEmpty() && maximum.getLast().number<number)
			maximum.removeLast();
		maximum.addLast(curData);
		
		curIndex++;  //別漏了這句
	}
	
	public void pop_front() {
		if(data.isEmpty()) {
			System.out.println("佇列為空,無法刪除!");
			return;
		}
		InternalData curData = data.removeFirst();
		if(curData.index==maximum.getFirst().index)
			maximum.removeFirst();
	}
	
	public int max() {
		if(maximum==null){
			System.out.println("佇列為空,無法刪除!");
			return 0;
		}
		return maximum.getFirst().number;
	}
	
	public static void main(String[] args) {
		QueueWithMax testQueue = new QueueWithMax();
	    // {2}
	    testQueue.push_back(2);
	    System.out.println(testQueue.max()==2);
	    // {2, 3}
	    testQueue.push_back(3);
	    System.out.println(testQueue.max()==3);
	    // {2, 3, 4}
	    testQueue.push_back(4);
	    System.out.println(testQueue.max()==4);
	    // {2, 3, 4, 2}
	    testQueue.push_back(2);
	    System.out.println(testQueue.max()==4);
	    // {3, 4, 2}
	    testQueue.pop_front();
	    System.out.println(testQueue.max()==4);
	    // {4, 2}
	    testQueue.pop_front();
	    System.out.println(testQueue.max()==4);
	    // {2}
	    testQueue.pop_front();
	    System.out.println(testQueue.max()==2);
	    // {2, 6}
	    testQueue.push_back(6);
	    System.out.println(testQueue.max()==6);
	    // {2, 6, 2}
	    testQueue.push_back(2);
	    System.out.println(testQueue.max()==6);
	    // {2, 6, 2, 5}
	    testQueue.push_back(5);
	    System.out.println(testQueue.max()==6);
	    // {6, 2, 5}
	    testQueue.pop_front();
	    System.out.println(testQueue.max()==6);
	    // {2, 5}
	    testQueue.pop_front();
	    System.out.println(testQueue.max()==5);
	    // {5}
	    testQueue.pop_front();
	    System.out.println(testQueue.max()==5);
	    // {5, 1}
	    testQueue.push_back(1);
	    System.out.println(testQueue.max()==5);	    
	}
}

  

true
true
true
true
true
true
true
true
true
true
true
true
true
true
QueueWithMax

 

收穫

  1.在定義private ArrayDeque<InternalData>  data時,別忘記了new ArrayDeque<InternalData>();否則在插入資料時,會丟擲NPE異常。

  2.進行刪除操作時,注意是否佇列是否為空。

 

更多:《劍指Offer》Java實現合集