【Java】 劍指offer(59-2) 隊列的最大值


 

本文參考自《劍指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實現合集  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM