1. 程式人生 > >實現一堆疊,要求三個操作,Pop,Push,GetMaxValue,時間均為O(1)

實現一堆疊,要求三個操作,Pop,Push,GetMaxValue,時間均為O(1)

  • 問題描述

擴充套件stack的實現,完成正常的push,pop操作,新增訪問最小(或最大)元素的介面Min(),使得push,pop,Min的時間複雜度都是O(1)。

  • 問題分析

拿到這道題,我們最先的思考往往是,設計一個演算法從棧中拿到最小值,所以開始考慮任何可以用來實現該功能的排序和查詢演算法。假設棧中有n個元素,一切排序和查詢都不可能實現O(1)的時間複雜度找到最小值。

再看題目,既然是擴充套件stack的實現,stack是一種資料結構,一種資料的組織方式,擴充套件它,也就允許我們對其資料組織方式和儲存內容作一些改變吧。所以我們就有了下面的思路:

把當前最小值再用個棧存起來,並且在進行push和pop操作的時維護它。維護要求如下:

  • 如果有比當前最小值大的元素入棧,當前最小值不變

  • 如果有比當前最小值小的元素入棧,當前最小值變為新加入元素,並壓入最小值棧(相等時也需做壓棧操作)

  • 如果有比當前最小值大的元素出棧,當前最小值不變(注意:彈出的操作時,一定不可能彈出比當前最小值還小的元素,也就是說如果你彈出了一個比當前最小值還小的元素,就證明你的那個當前最小值不是當前最小值)

  • 如果有和當前最小值的元素相同出棧,當前最小值變為當前當前最小值入棧之前那個最小值,當前最小值退出。

綜上,我們發現一個規律:對於最小值而言,如果有更小的數入棧,需要將其儲存為當前最小,如果當前最小數出棧,當前最小數變成當前最小數入棧之前那個最小數,所以,對於最小數而言也具有先進後出,後進先出的特點,只是並不是每次push和pop操作都牽涉到最小數的進出。所以我們考慮用雙棧來實現,一個棧用來存放資料,滿足棧資料結構原始要求,一個棧用來存放最小值,在每次push和pop操作執行時,按照上面的規則維護最小值棧。

  • 解決方法
public class SpecialStack {
    Stack stack1 = new Stack();
    Stack stackMin = new Stack();// 存放求最小值的棧
    Stack stackMax = new Stack();// 存放求最大值的棧

    public void push(E e) {
        stack1.push(e);

        if (stackMin.isEmpty() || e.compareTo(stackMin.peek()) < 0)
            stackMin.push(e);// 若最小棧為空,push進stack時,就同時把它push進stackMin;
else if (e.compareTo(stackMin.peek()) > 0) stackMin.push(stackMin.peek()); if (stackMax.isEmpty() || e.compareTo(stackMin.peek()) > 0) stackMax.push(e); else if (e.compareTo(stackMax.peek()) < 0) stackMin.push(stackMax.peek()); } public E pop()// 一定要記著,非空才能pop() { if (!stack1.isEmpty() && !stackMin.isEmpty() && !stackMax.isEmpty()) { E e = stack1.pop(); stackMin.pop(); stackMax.pop(); return e; } else { System.out.println("棧已經為空了"); return null; } } public E getMin() { return stackMin.peek(); } public E getMax() { return stackMax.peek(); } public E getMed() { E[] ss = (E[]) stack1.toArray();// stack1.toArray()返回的是Object[], // 棧----->陣列 Arrays.sort(ss); return ss[ss.length / 2]; } }

相關推薦

實現堆疊要求操作PopPush,GetMaxValue時間O(1)

問題描述 擴充套件stack的實現,完成正常的push,pop操作,新增訪問最小(或最大)元素的介面Min(),使得push,pop,Min的時間複雜度都是O(1)。 問題分析 拿到這道題,我們最先的思考往往是,設計一個演算法從棧中拿到最小值,所以

輸入m學生每個學生有4門課在主調函式中輸入學生的相關資訊編寫三個函式: (1)求第一門課的平均分; (2)找出有兩門課以上不及格的學生並輸出他們的學號和全部成績,要求用指標函式實現:fl

  輸入m個學生,每個學生有4門課,在主調函式中輸入學生的相關資訊,編寫三個函式: (1)求第一門課的平均分; (2)找出有兩門課以上不及格的學生,並輸出他們的學號和全部成績,要求用指標函式實現:float*Search(float(*p)[4],int n); (3)找出

從鍵盤輸入整數a、b、c要求將輸出的資料按從大到小排序後輸出。

#include<stdio.h> int main() { int a,b,c,t; scanf("%d%d%d",&a,&b,&c); if(a>b) { t=a; a=b; b=t; } if(a>c) { t=a; a=c; c=t

實驗5.1(舊)寫出一個由一個主函數和小函數組成的程序該程序可以從某字符串中刪除指定字符。

using span ring font 修改 mes out 部分 nbsp 實驗目的: 輸入一串字符,再輸入一個指定字符,將字符串中刪去指定字符再顯示出來。要求程序把輸入字符串、刪除指定字符和顯示字符串的功能分別在各自單獨的.cpp文件由外部函數來處理,主文件中

【資料結構】實現一個棧要求實現Push(出棧)、Pop(入棧)、Min(返回最小值的操作)的時間複雜度O(1)

實現一個棧,要求實現Push(出棧)、Pop(入棧)、Min(返回最小值的操作)的時間複雜度為O(1) 在棧中操作的話,push和pop的時間複雜度就是O(1),所以我們只用實現Min(返回最小值的操作)的時間複雜度為O(1), 思想就是用兩個棧,一個就是普通的存取資料的

實現一個棧Stack要求實現Push(出棧)、Pop(入棧)、 Min(返回最小值的操作)的時間複雜度O(1)

利用兩個棧 1. 一個用來儲存最小的元素 smin 2. 一個用來儲存所有元素 scur 3. 入棧時,scur直接壓入,smin棧頂與目標元素比較,若小之則壓入,否則不做處理 4. 出棧時,s

實現一個棧Stack要求實現Push(出棧)、Pop(入棧)、Min(返回最小值的操作)的時間複雜度O(1)

這裡的要求呢,跟我們平時的stack操作是一樣的,那什麼地方不同呢?多了一個min方法,並且要求時間複雜度為O(1),那該怎麼做呢?O(1)的意思就是說,要用了,直接就能拿到,就好比陣列直到下標一樣,直接取。 那麼如果能夠將一個棧的棧頂一直存放的都是最小值呢?

提出種資料結構支援pushpop操作以及第操作findMin,返回最小值所有操作O(1)最壞時間執行

public class MyStack1 { private int[] data;//用於支援push和pop操作的陣列 private int[] minData;//用於支援findMin操作的陣列,儲存一個最小值序列 priva

【棧佇列】實現一個棧Stack要求實現Push(出棧)、Pop(入棧)、Min(返回最小值的操作)的時間複雜度O(1)

問題分析 要記錄從當前棧頂到棧底元素的最小值,很容易想到用一個變數,每push一個元素更新一次變數的值。那麼問題來了,當執行pop操作時,上一次的最小值就找不到了。 解決方法 方法1、 使用一個棧。元素x入棧時,執行一次push(x),再push(min

騰訊面試題:模板實現一個棧要求Push(入棧)Pop(出棧)Max(返回最大值的操作)的時間複雜度O(1)

解題思路:要用模板實現亂序入棧的陣列每次pop()出棧都能得到當前棧中Max的最大值,就必須在push()入棧時進行維護操作,使的每次入棧的元素都能夠找到合適的位置並push(),每次push()操作完成後棧中的元素都能夠按從棧頂到棧底從大到小排列即可。這就需要寫一個不同於常

線程打印ABC10次ABCABCABC....

控制臺應用程序 pre event main names .com obj ace nap // ConsoleApplication2.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream&g

大數據之搭建HDP環境節點

com 新的 防火墻 cdh 實驗環境 只需要 包名 connector start (一)實驗環境l 實驗介質?CentOS-7-x86_64-Everything-1708.iso?jdk-8u144-linux-x64.tar.gz?ambari-2.6.0.0-ce

TCP報文格式和次握手——次握手tcp包(header+data)此外TCP 報文段中的數據部分是可選的在一個連接建立和一個連接終止時雙方交換的報文段僅有 TCP 首部。

pan 內容 由於 clas nts data 奇偶校驗 rom 加載中 from:https://blog.csdn.net/mary19920410/article/details/58030147 TCP報文是TCP層傳輸的數據單元,也叫報文段。 1、端口號:用來標

搭建CDH實驗環境節點例的安裝配置

包名 技術 move remote type -s 用戶密碼 reat 51cto (一)實驗環境l 實驗介質n CentOS-7-x86_64-Everything-1708.ison jdk-8u161-linux-x64.rpmn cloudera-manager-c

資料庫擴充套件性設計:使用二進位制解決條記錄關聯多狀態的問題(轉)可以嘗試一下

程式開發中,經常遇到一條記錄有多個狀態位,比如一條商品,他屬於熱門,新品,特賣。我們的資料庫如何設計呢? 一般有幾種方法 (1)建立關聯表 關聯表字段:關係Id,商品Id,屬性Id 查詢:使用關聯表的方式,查詢某屬性的商品。 程式:寫入時,寫商品表和關聯表;

給出一個不多於5位的正整數求解問題。

題目:給出一個不多於5位的正整數,要求: 1.求出它是幾位數; 2.分別輸出每一位數字; 3.按逆序輸出各位數字。   解答 第一問: int n,m=1;  int a; scanf("%d",&n);  a=n; //方法一 print

bootstarp table 初始化列的時候添加操作按鈕事件

/** * 初始化表格的列 */ TaskError.initColumn = function () { return [ {field: 'selectItem', radio: true}, {title: '', field: '

使用idea的時候遇到的n問題:第一是關於註冊過期怎麼才可以永久使用第二是關於maven繫結到idea。。。。第n。。

關於idea的n個問題,我也是網上到處找,然後發現下邊部落格幫我解決了相關問題: 問題一:一個是關於註冊過期,怎麼才可以永久使用 https://blog.csdn.net/f317363184/article/details/78808925?utm_source=blogxgwz4

《王者榮耀》“中年人”的遊戲故事

@央廣軍事11月10日訊息,2018中國航展上首次公開展出的“瞭望者Ⅱ”察打一體導彈無人艇,是剛剛成功進行首發導彈飛行試驗命中靶心的實艇,試驗成功後隨即吊裝到展位與公眾見面。據媒體此前報道,該艇是中國第一艘導彈無人艇,也是繼以色列拉斐爾海上騎士後全球第二個成功發射導彈的無人艇,填補了國內導彈無人艇這一技術空白