算法體系-26 第二十六節:第26節:單調棧結構 (5節)

一 單調棧知識講解

1.1描述

一個數組里面想的到每個位置與他最近的左邊和右邊比他小的最近的信息

1.2 分析
通過單調棧的特點,for遍歷數組中的每個數,當前數來的時候對比單調棧中的數進行每個數的左右判斷完滿足條件的進行更新到當前i種的

int[][] res = new int[arr.length][2]; 里0和1中去

res[j][0] = leftLessIndex;
res[j][1] = i;

1.2.1 無重復值版本

1.2.2 有重復值版本

1.3 代碼
無重復值情況

// arr = [ 3, 1, 2, 3]//         0  1  2  3//  [//     0 : [-1,  1]//     1 : [-1, -1]//     2 : [ 1, -1]//     3 : [ 2, -1]//  ]public static int[][] getNearLessNoRepeat(int[] arr) {int[][] res = new int[arr.length][2];// 只存位置!Stack<Integer> stack = new Stack<>();for (int i = 0; i < arr.length; i++) { // 當遍歷到i位置的數,arr[i]while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) {int j = stack.pop();int leftLessIndex = stack.isEmpty() ? -1 : stack.peek();res[j][0] = leftLessIndex;res[j][1] = i;}stack.push(i);}while (!stack.isEmpty()) {int j = stack.pop();int leftLessIndex = stack.isEmpty() ? -1 : stack.peek();res[j][0] = leftLessIndex;res[j][1] = -1;}return res;}

有重復值情況

public static int[][] getNearLess(int[] arr) {int[][] res = new int[arr.length][2];Stack<List<Integer>> stack = new Stack<>();for (int i = 0; i < arr.length; i++) { // i -> arr[i] 進棧while (!stack.isEmpty() && arr[stack.peek().get(0)] > arr[i]) {List<Integer> popIs = stack.pop();int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1);for (Integer popi : popIs) {res[popi][0] = leftLessIndex;res[popi][1] = i;}}if (!stack.isEmpty() && arr[stack.peek().get(0)] == arr[i]) {stack.peek().add(Integer.valueOf(i));} else {ArrayList<Integer> list = new ArrayList<>();list.add(i);stack.push(list);}}while (!stack.isEmpty()) {List<Integer> popIs = stack.pop();int leftLessIndex = stack.isEmpty() ? -1 : stack.peek().get(stack.peek().size() - 1);for (Integer popi : popIs) {res[popi][0] = leftLessIndex;res[popi][1] = -1;}}return res;}

二 單調棧應用實例1

2.1 描述

給定一個只包含正數的數組arr,arr中任何一個子數組sub, 一定都可以算出(sub累加和 )* (sub中的最小值)是什么, 那么所有子數組中(子數組的index一定是連續的),這個值最大是多少?

2.2 分析

如果我們求出必須以每個位置為最小值情況下的答案,那么我們整體答案一定在其中

首先以當前index為作為最小值的子數組,看他的指標值是多少,依次for,答案一定在其中將max選出來就行了

如果子數組我必須以X為最小值,我如何能夠得到他以哪個子數組他的累加和最大呢,也就是找到左邊離你最近的比你最小的,右邊離你最近的比你小的,中間包含x整個這段全要就是X為最小值累加和最大的子數組

2.3 代碼

package class25;import java.util.Stack;public class Code02_AllTimesMinToMax {public static int max1(int[] arr) {int max = Integer.MIN_VALUE;for (int i = 0; i < arr.length; i++) {for (int j = i; j < arr.length; j++) {int minNum = Integer.MAX_VALUE;int sum = 0;for (int k = i; k <= j; k++) {sum += arr[k];minNum = Math.min(minNum, arr[k]);}max = Math.max(max, minNum * sum);}}return max;}public static int max2(int[] arr) {int size = arr.length;int[] sums = new int[size];sums[0] = arr[0];for (int i = 1; i < size; i++) {sums[i] = sums[i - 1] + arr[i];}int max = Integer.MIN_VALUE;Stack<Integer> stack = new Stack<Integer>();for (int i = 0; i < size; i++) {while (!stack.isEmpty() && arr[stack.peek()] >= arr[i]) {int j = stack.pop();max = Math.max(max, (stack.isEmpty() ? sums[i - 1] : (sums[i - 1] - sums[stack.peek()])) * arr[j]);}stack.push(i);}while (!stack.isEmpty()) {int j = stack.pop();max = Math.max(max, (stack.isEmpty() ? sums[size - 1] : (sums[size - 1] - sums[stack.peek()])) * arr[j]);}return max;}public static int[] gerenareRondomArray() {int[] arr = new int[(int) (Math.random() * 20) + 10];for (int i = 0; i < arr.length; i++) {arr[i] = (int) (Math.random() * 101);}return arr;}public static void main(String[] args) {int testTimes = 2000000;System.out.println("test begin");for (int i = 0; i < testTimes; i++) {int[] arr = gerenareRondomArray();if (max1(arr) != max2(arr)) {System.out.println("FUCK!");break;}}System.out.println("test finish");}// 本題可以在leetcode上找到原題// 測試鏈接 : https://leetcode.com/problems/maximum-subarray-min-product/// 注意測試題目數量大,要取模,但是思路和課上講的是完全一樣的// 注意溢出的處理即可,也就是用long類型來表示累加和// 還有優化就是,你可以用自己手寫的數組棧,來替代系統實現的棧,也會快很多public static int maxSumMinProduct(int[] arr) {int size = arr.length;long[] sums = new long[size];sums[0] = arr[0];for (int i = 1; i < size; i++) {sums[i] = sums[i - 1] + arr[i];}long max = Long.MIN_VALUE;int[] stack = new int[size];int stackSize = 0;for (int i = 0; i < size; i++) {while (stackSize != 0 && arr[stack[stackSize - 1]] >= arr[i]) {int j = stack[--stackSize];max = Math.max(max,(stackSize == 0 ? sums[i - 1] : (sums[i - 1] - sums[stack[stackSize - 1]])) * arr[j]);}stack[stackSize++] = i;}while (stackSize != 0) {int j = stack[--stackSize];max = Math.max(max,(stackSize == 0 ? sums[size - 1] : (sums[size - 1] - sums[stack[stackSize - 1]])) * arr[j]);}return (int) (max % 1000000007);}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43569.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43569.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43569.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WPScan漏洞掃描工具的介紹及使用

目錄 1. 介紹2. 常用參數 1. 介紹 WPScan是Kali Linux默認自帶的一款漏洞掃描工具&#xff0c;它采用Ruby編寫&#xff0c;能夠掃描WordPress網站中的多種安全漏洞&#xff0c;其中包括WordPress本身的漏洞、插件漏洞和主題漏洞&#xff0c;最新版本WPScan的數據庫中包含超過18…

采用3種稀疏降噪模型對心電信號進行降噪(Matlab R2021B)

心電信號采集自病人體表&#xff0c;是一種無創性的檢測手段。因此&#xff0c;心電信號采集過程中&#xff0c;本身也已經包含了機體內部其他生命活動帶來的噪聲。同時&#xff0c;由于采集設備和環境中存在電流的變化&#xff0c;產生電磁發射等物理現象&#xff0c;會對心電…

學習測試7-ADB的使用

ADB是什么&#xff1f; ADB&#xff0c;即 Android Debug Bridge&#xff08;安卓調試橋&#xff09; 是一種允許模擬器或已連接的 Android 設備進行通信的命令行工具&#xff0c;它可為各種設備操作提供便利&#xff0c;如安裝和調試應用&#xff0c;并提供對 Unix shell&…

最新全國1-5級標準河流水系矢量數據

2023最新全國一級&#xff5e;五級標準河流水系 shp 矢量數據 2023最新全國一級&#xff5e;五級標準河流水系 shp 矢量數據 Arcgis 五級河流水系全國合集和按省區分 坐標系&#xff1a;wgs84 更新年份&#xff1a;2023年 包含20230SM提取全國超詳細水體 Arcgis 矢量數據&a…

AcWing 849. Dijkstra求最短路 I

給定一個 n 個點 m 條邊的有向圖&#xff0c;圖中可能存在重邊和自環&#xff0c;所有邊權均為正值。 請你求出 11 號點到 n 號點的最短距離&#xff0c;如果無法從 1 號點走到 n 號點&#xff0c;則輸出 ?1。 輸入格式 第一行包含整數 n 和 m。 接下來 m 行每行包含三個整…

Python從Excel表中查找指定數據填入新表

#讀取xls文件中的數據 import xlrd file "原表.xls" wb xlrd.open_workbook(file) #讀取工作簿 ws wb.sheets()[0] #選第一個工作表 data [] for row in range(7, ws.nrows): name ws.cell(row, 1).value.strip() #科室名稱 total1 ws.cell(row, 2…

TIA博途與威綸通觸摸屏無實物仿真調試的具體方法示例

TIA博途與威綸通觸摸屏無實物仿真調試的具體方法示例 準備條件: TIA PORTAL V16 S7-PLCSIM V16 EasyBuilderPro V6.9.1 NetToPLCsim V1.2.5 如有需要,可以在這個鏈接中下載 NetToPLCSim - Browse Files at SourceForge.net538 weekly downloads3 weekly downloads12 weekly d…

QTransform 解析

實例: 以點(100,100) 圍繞點(200,150)旋轉45后的坐標, 采用QTransform 類方法實現移動變換. Test1 采用一個QTransform 對象,通過連續的變換后,發現最后的結果與預先的不一致. 原因: 當trans1.translate(-200., -150.); 后,坐標系的原點變成了-200,-150. 之后trans1.rotat…

LoveDA: 遙感土地覆蓋數據集的領域自適應語義分割

引入了土地覆蓋域自適應語義分割(LoveDA)數據集來推進語義和可轉移學習。LoveDA數據集包含來自三個不同城市的5987張高分辨率圖像和166768個帶注釋的對象。與現有數據集相比&#xff0c;LoveDA數據集包含兩個領域(城市和農村)&#xff0c;這帶來了相當大的挑戰&#xff0c;因為…

華為OD機試題-貪心歌手

題目解析 題目描述&#xff1a; 歌手準備從 A 城去 B 城參加演出 按照合同&#xff0c;他必須在 T 天內趕到。歌手途徑 N 座城市。歌手不能往回走。每兩座城市之間需要的天數都可以提前獲知。歌手在每座城市都可以在路邊賣唱賺錢。經過調研&#xff0c;歌手提前獲知了每座城市…

C# AOP面向切面編程

AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面編程&#xff09;是一種編程范式&#xff0c;旨在將橫切關注點&#xff08;Cross-cutting Concerns&#xff09;從業務邏輯中分離出來。在傳統的面向對象編程中&#xff0c;橫切關注點&#xff08;如日志記錄、…

R包:蛋白質組學質控評估PTXQC包

介紹 PTXQC包是2016年發表在J Proteome Res期刊上的R包&#xff0c;它主要是對MaxQuant輸出結果進行提取處理從而獲得評估蛋白質質量結果。 安裝 從github安裝&#xff0c;安裝過程會自動構建tutorial。 devtools::install_github("cbielow/PTXQC", build_vignet…

AI數字人直播saas系統源碼部署火爆!無人直播系統全攻略

隨著直播行業的日益興盛&#xff0c;各種直播模式和玩法不斷涌現。其中&#xff0c;AI數字人直播更是憑借著其在降本增效的獨特優勢而在眾多直播模式中脫穎而出&#xff0c;成為了眾多企業已經引進或計劃引進的新型技術。而各大數字人源碼廠商推出的AI數字人直播saas系統源碼部…

面試題07-09

知道了 InnoDB 的索引實現后&#xff0c;就很容易明白為什么不建議使用過長的字段作為主鍵&#xff0c;因為所有輔助索引都引用主索引&#xff0c;過長的主索引會令輔助索引變得過大。再例如&#xff0c;用非單調的字段作為主鍵在 InnoDB 中不是個好主意&#xff0c;因為 InnoD…

走拼箱貨必看海運拼箱的實用技巧

在國際海運運輸中&#xff0c;海運拼箱適用于貨物數量較少或體積不足以填滿整個集裝箱的情況。 海運拼箱貨物通常由物流公司或貨代進行組織和管理。多個貨主的貨物通過合理拼裝&#xff0c;使集裝箱空間得到充分利用。 那么&#xff0c;在海運拼箱和整柜有哪些不同&#xff0c…

Linux -- 認識gcc/g++、代碼的編譯過程

目錄 前言&#xff1a; 使用 gcc/g&#xff1a; 代碼的編譯過程&#xff1a; 預處理&#xff1a; 頭文件展開&#xff1a; 宏替換去注釋&#xff1a; ?編輯 條件編譯&#xff1a; 編譯&#xff1a; 匯編&#xff1a; 鏈接&#xff1a; 動態庫&#xff08;動態鏈…

使用Simulink基于模型設計(二):系統定義和布局

Simulink模型的頂層系統布局是許多工程團隊可以使用的公共環境&#xff0c;是基于模型的設計范式&#xff1a;分析、設計、檢驗和實現。您可以通過確定模型的結構和各個組件來定義頂層系統。然后&#xff0c;您可以將模型按照層次結構進行組織&#xff0c;分別與系統的各個組件…

【鴻蒙學習筆記】交互事件

官方文檔&#xff1a;交互事件 目錄標題 分類交互事件-觸屏交互事件-手勢事件單一手勢 分類 交互事件-觸屏 在組件上按下(Down) , 滑動(Move) , 抬起(up)時觸發的回調事件。包括點擊事件、觸摸事件和拖拽事件 交互事件-手勢事件 在手機上點擊打開應用 , 長按后拖動應用 , 這…

自動化數據集成的BI工具,為你提供決策洞察力

傳統的商業智能&#xff08;BI&#xff09;報表系統采用的是“業務提報表需求&#xff0c;IT進行開發”的模式。決策管理者和業務人員提出用報表等來展示經營管理數據的需求&#xff1b;接著IT響應需求&#xff0c;進行需求溝通、數據處理加工、報表開發等主體工作&#xff1b;…

使用java代碼取本月第一個工作日

根據參數或當前月&#xff0c;獲取本月第一個工作日 文章目錄 根據參數或當前月&#xff0c;獲取本月第一個工作日前言一、根據當前日期獲取當前月的第一個工作日二、根據參數日期&#xff0c;獲取參數月的第一個工作日。總結 前言 這里我們列舉兩個方法&#xff1a; 1、沒有參…