[連結串列]leetcode1019-連結串列中的下一個更大節點
[連結串列]–連結串列中的下一個更大節點
題目連結
題目
給出一個以頭節點 head 作為第一個節點的連結串列。連結串列中的節點分別編號為:node_1, node_2, node_3, … 。
每個節點都可能有下一個更大值(next larger value):對於 node_i,如果其 next_larger(node_i) 是 node_j.val,那就有 j > i 且 node_j.val > node_i.val,而 j 是可能的選項中最小的那個。如果不存在這樣的 j,那麼下一個更大值為 0 。
返回整數答案陣列 answer,其中 answer[i] = next_larger(node_{i+1}) 。
注意:在下面的示例中,諸如 [2,1,5] 這樣的輸入(不是輸出)是連結串列的序列化表示,其頭節點的值為 2,第二個節點值為 1,第三個節點值為 5 。
示例
輸入:[2,1,5]
輸出:[5,5,0]
輸入:[2,7,4,3,5]
輸出:[7,0,5,5,0]
輸入:[1,7,5,1,9,2,5,1]
輸出:[7,9,9,9,0,5,0,0]
解析
見過!但是做的不是連結串列形式,陣列!不如…
- 將節點值全部取出來裝入 list,裝作是一個動態陣列;
- 使用一個雙重迴圈遍歷 list,找出後面第一個大於自身的數裝入陣列即可,沒找到?那就是 0了。
這時間就…說不出口
程式碼實現
public class Solution1019 {
/**
* Definition for singly-linked list
*/
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
/**
* 1.將連結串列的節點值裝入 list
* 2.遍歷連結串列找出第一個大於自身的數裝入 result , 沒有裝入值的預設是 0
* 時間複雜度 O(N^2)
*/
public int[] nextLargerNodes(ListNode head) {
if (head == null) return null;
List<Integer> list = new ArrayList<>();
ListNode cur = head;
// 取出節點值
while (cur != null) {
list.add(cur.val);
cur = cur.next;
}
// 找出第一個大於自身的數即可
int[] result = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
if (list.get(j) > list.get(i)) {
result[i] = list.get(j);
break;
}
}
}
return result;
}
}
單調棧!也就是這個棧內元素是單調遞增或者是單調遞減的。
- 還是取出所有的節點值裝入 list;
- 從後向前遍歷 list,對於當前元素的處理就是維護一個單調遞增棧:在棧不為空的前提下將所有不大於當前元素的都彈出棧;
- 對於當前元素來說:
(1)棧為空:說明後面所有元素都小於他,所以對應陣列位置是0;
(2)棧不為空:那棧頂元素就是後面所有元素中第一個大於他的,對應陣列位置就是棧頂元素了。- 當前元素壓棧即可。
程式碼實現
public class Solution1019 {
/**
* Definition for singly-linked list
*/
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
/**
* 單調棧
* 1.遍歷所有節點將值放入 list
* 2.單調棧: 棧頂元素最小
* 1.棧中存放的是後面大於當前遍歷到的 list 元素的最大值
* 2.從後向前遍歷 list, 將棧中所有小於當前元素的都彈出去, 維護單調棧
* 3.第二步之後棧頂元素(如果存在)必然是後面第一個大於當前元素的值,即下一個更大節點: 棧空說明遍歷過的元素自己最大
* 4.每次迴圈進行完將當前元素壓棧, 進行下一次判斷
*/
public int[] nextLargerNodes(ListNode head) {
if (head == null) return null;
List<Integer> list = new ArrayList<>();
// 取出節點值
while (head != null) {
list.add(head.val);
head = head.next;
}
// 使用棧存放對應位置的 list 元素以及其之後元素中最大的值
int[] result = new int[list.size()];
Stack<Integer> stack = new Stack<>();
for (int i = list.size()-1; i >= 0; i--) {
// 所有小於等於 list.get(i) 的都彈出去
// 棧裡面存放的都大於 list,get(i), 那麼第一個大於 list 元素的就是棧頂元素
while (!stack.isEmpty() && stack.peek() <= list.get(i)) {
stack.pop();
}
// 棧不為空時說明棧頂元素就是當前大於 list 元素的第一個元素
// 棧為空說明當前元素大於遍歷過的所有元素, 也就是說後面沒有比它更大的了, 所以此時下一個更大節點是 0
result[i] = stack.isEmpty() ? 0 : stack.peek();
stack.push(list.get(i));
}
return result;
}
}
-----------------------------------------------------------------------------有始有終分割線----------------------------------------------------------------------------------
相關文章
- 1019. 連結串列中的下一個更大節點
- 【連結串列問題】刪除單連結串列的中間節點
- 2024/11/27 【連結串列】LeetCode 24 兩兩交換連結串列中的節點 & LeetCode 19 刪除連結串列的倒數第N個節點LeetCode
- 【連結串列問題】打卡3:刪除單連結串列的中間節點
- Day4(連結串列)|24. 兩兩交換連結串列中的節點 & 19.刪除連結串列的倒數第N個節點 & 面試題 02.07. 連結串列相交 &142.環形連結串列II面試題
- K個節點翻轉連結串列
- 【連結串列問題】打卡2:刪除單連結串列的第 K個節點
- 特定深度節點連結串列
- **24. 兩兩交換連結串列中的節點****19.刪除連結串列的倒數第N個節點****面試題 02.07. 連結串列相交****142.環形連結串列II**面試題
- Redis筆記 — 連結串列和連結串列節點的API函式(三)Redis筆記API函式
- 【LeetCode連結串列#9】圖解:兩兩交換連結串列節點LeetCode圖解
- 定義一個函式,輸入一個連結串列的頭節點,反轉該連結串列並輸出反轉後連結串列的頭節點函式
- Day 4 | 24. 兩兩交換連結串列中的節點 、 19.刪除連結串列的倒數第N個節點 、面試題 02.07. 連結串列相交 、142.環形連結串列II面試題
- 兩個連結串列的第一個公共節點
- leetcode----刪除連結串列中的節點LeetCode
- 連結串列中環的入口結點
- 第四天:● 24. 兩兩交換連結串列中的節點 ● 19.刪除連結串列的倒數第N個節點 ● 面試題 02.07. 連結串列相交 ● 142.環形連結串列II面試題
- 連結串列 - 單向連結串列
- 連結串列-迴圈連結串列
- 連結串列-雙向連結串列
- 連結串列中的節點每k個一組翻轉
- 雙向連結串列 尾節點插入
- 876. 連結串列的中間結點
- 連結串列4: 迴圈連結串列
- 連結串列-雙向通用連結串列
- 連結串列-單連結串列實現
- 結點插入到單連結串列中
- 【連結串列問題】打卡8:複製含有隨機指標節點的連結串列隨機指標
- 程式碼隨想錄第4天 | 24. 兩兩交換連結串列中的節點、19.刪除連結串列的倒數第N個節點、面試題 02.07. 連結串列相交、142.環形連結串列II面試題
- 【劍指offer】【3】輸入一個連結串列,從尾到頭列印連結串列每個節點的值。
- 166. 連結串列倒數第n個節點
- 兩個連結串列的第一個公共結點
- 連結串列-雙向非通用連結串列
- 【LeetCode】->連結串列->通向連結串列自由之路LeetCode
- 連結串列入門與插入連結串列
- Leetcode_86_分割連結串列_連結串列LeetCode
- 連結串列倒數第k個結點
- leetcode 24 兩兩交換連結串列中的節點LeetCode