给定一个整数链表L ,任务是返回一个整数链表,使得它包含给定链表中每个元素的下一个更大的元素。如果任何元素都没有更大的元素,则为其插入0 。
例子:
Input: 2->1->3->0->5
Output: 3->3->5->5->0
Input: 1->2->3
Output: 2->3->0
朴素的方法:朴素的方法是遍历链表L ,对于链表中的每个元素,通过从当前元素遍历整个字符串来查找列表中的下一个更大的元素。
时间复杂度: O(N 2 )
高效的方法:可以通过维护一个单调递减的元素堆栈来优化上述朴素的方法。如果找到更大的元素,则将其追加到结果链表L’ 中,否则追加0 。以下是步骤:
- 将第一个节点压入堆栈。
- 一个接一个地选择节点的其余部分,并在循环中执行以下步骤:
- 将当前节点标记为下一个节点。
- 如果堆栈不为空,则将堆栈的顶部节点值与下一个节点值进行比较。
- 如果下一个节点值大于顶节点值,则从堆栈中弹出顶节点,下一个是弹出节点的下一个更大的元素。
- 当弹出的节点值小于下一个节点值时,继续从堆栈中弹出节点。下一个节点将成为所有此类弹出节点的下一个更大的元素。
- 最后,压入堆栈中的下一个节点。
- 在步骤 2 中的循环结束后,从堆栈中弹出所有节点并打印0作为它们的下一个元素。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// List Node
struct ListNode {
int val;
ListNode* next;
ListNode(int x)
{
val = x;
next = NULL;
}
};
// Function to reverse the LL
void rev(ListNode** head)
{
ListNode *pre, *curr, *nex;
pre = NULL;
curr = *head;
nex = curr->next;
// Till current is not NULL
while (curr) {
curr->next = pre;
pre = curr;
curr = nex;
nex = (curr)
? curr->next
: NULL;
}
*head = pre;
}
// Function to print a LL node
void printList(ListNode* head)
{
while (head) {
cout << head->val
<< ' ';
head = head->next;
}
}
// Function to find the next greater
// element in the list
ListNode* nextLargerLL(ListNode* head)
{
if (head == NULL)
return NULL;
// Dummy Node
ListNode* res
= new ListNode(-1);
ListNode* temp = res;
// Reverse the LL
rev(&head);
stack st;
while (head) {
// Initial Condition
if (st.empty()) {
temp->next
= new ListNode(0);
st.push(head->val);
}
else {
// Maintain Monotonicity
// Decreasing stack of element
while (!st.empty()
&& st.top()
<= head->val)
st.pop();
// Update result LL
if (st.empty()) {
temp->next
= new ListNode(0);
st.push(head->val);
}
else {
temp->next
= new ListNode(st.top());
st.push(head->val);
}
}
head = head->next;
temp = temp->next;
}
// Delete Dummy Node
temp = res;
res = res->next;
delete temp;
// Reverse result LL
rev(&res);
return res;
}
// Driver Code
int main()
{
// Given Linked List
ListNode* head = new ListNode(2);
ListNode* curr = head;
curr->next = new ListNode(1);
curr = curr->next;
curr->next = new ListNode(3);
curr = curr->next;
curr->next = new ListNode(0);
curr = curr->next;
curr->next = new ListNode(5);
curr = curr->next;
// Function Call
printList(nextLargerLL(head));
return 0;
}
Java
// Java program for the above approach
import java.util.*;
public class linkedList
{
ListNode head = null;
// ListNode
class ListNode
{
int val;
ListNode next;
public ListNode(int val)
{
this.val = val;
next = null;
}
}
// Function to reverse the Linked List
ListNode reverse(ListNode head)
{
ListNode prev = null, next = null,
curr = head;
while (curr != null)
{
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to find the next greater
// element in the list
ListNode nextLargerLL(ListNode head)
{
if (head == null)
return head;
// Dummy Node
ListNode res = new ListNode(-1);
ListNode temp = res;
// Reverse the Linked List
head = reverse(head);
Stack st = new Stack<>();
while (head != null)
{
// Initial Condition
if (st.empty())
{
temp.next = new ListNode(0);
st.push(head.val);
}
else {
// Maintain Monotonicity
// Decreasing stack of element
while (!st.empty() &&
st.peek() <= head.val)
st.pop();
// Update result Linked List
if (st.empty())
{
temp.next = new ListNode(0);
st.push(head.val);
}
else
{
temp.next = new ListNode(st.peek());
st.push(head.val);
}
}
head = head.next;
temp = temp.next;
}
temp = res;
res = res.next;
// Reverse result Linked List
res = reverse(res);
return res;
}
public void push(int new_data)
{
/* allocate node */
ListNode new_node = new ListNode(new_data);
/* link the old list off the new node */
new_node.next = head;
/* move the head to point to the new node */
head = new_node;
}
// Utility function to print the linked list
public void printList(ListNode head)
{
ListNode temp = head;
while (temp != null)
{
System.out.print(temp.val + " ");
temp = temp.next;
}
}
// Driver Code
public static void main(String[] args)
{
linkedList ll = new linkedList();
ll.push(5);
ll.push(0);
ll.push(3);
ll.push(1);
ll.push(2);
// Function Call
ll.printList(ll.nextLargerLL(ll.head));
}
}
Python3
# Python3 program for the above approach
# List Node
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
# Function to reverse the LL
def rev(head):
pre = None;
curr = head;
nex = curr.next;
# Till current is not None
while (curr):
curr.next = pre;
pre = curr;
curr = nex;
nex = (curr.next) if curr else None
head = pre
return head
# Function to print a LL node
def printList(head):
while(head):
print(str(head.val), end = ' ')
head = head.next;
# Function to find the next greater
# element in the list
def nextLargerLL(head):
if (head == None):
return None;
# Dummy Node
res = ListNode(-1);
temp = res;
# Reverse the LL
head = rev(head);
st = []
while (head):
# Initial Condition
if (len(st) == 0):
temp.next = ListNode(0);
st.append(head.val);
else:
# Maintain Monotonicity
# Decreasing stack of element
while (len(st) != 0 and st[-1]<= head.val):
st.pop();
# Update result LL
if (len(st) == 0):
temp.next = ListNode(0);
st.append(head.val);
else:
temp.next = ListNode(st[-1]);
st.append(head.val);
head = head.next;
temp = temp.next;
# Delete Dummy Node
temp = res;
res = res.next;
del temp;
# Reverse result LL
res = rev(res);
return res;
# Driver Code
if __name__=='__main__':
# Given Linked List
head = ListNode(2);
curr = head;
curr.next = ListNode(1);
curr = curr.next;
curr.next = ListNode(3);
curr = curr.next;
curr.next = ListNode(0);
curr = curr.next;
curr.next = ListNode(5);
curr = curr.next;
# Function Call
printList(nextLargerLL(head));
# This code is contributed by rutvik_56
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class linkedList{
ListNode head = null;
// ListNode
public class ListNode
{
public int val;
public ListNode next;
public ListNode(int val)
{
this.val = val;
next = null;
}
}
// Function to reverse the Linked List
ListNode reverse(ListNode head)
{
ListNode prev = null, next = null,
curr = head;
while (curr != null)
{
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
// Function to find the next greater
// element in the list
ListNode nextLargerLL(ListNode head)
{
if (head == null)
return head;
// Dummy Node
ListNode res = new ListNode(-1);
ListNode temp = res;
// Reverse the Linked List
head = reverse(head);
Stack st = new Stack();
while (head != null)
{
// Initial Condition
if (st.Count == 0)
{
temp.next = new ListNode(0);
st.Push(head.val);
}
else
{
// Maintain Monotonicity
// Decreasing stack of element
while (st.Count != 0 &&
st.Peek() <= head.val)
st.Pop();
// Update result Linked List
if (st.Count == 0)
{
temp.next = new ListNode(0);
st.Push(head.val);
}
else
{
temp.next = new ListNode(st.Peek());
st.Push(head.val);
}
}
head = head.next;
temp = temp.next;
}
temp = res;
res = res.next;
// Reverse result Linked List
res = reverse(res);
return res;
}
public void Push(int new_data)
{
// Allocate node
ListNode new_node = new ListNode(new_data);
// Link the old list off the new node
new_node.next = head;
// Move the head to point to the new node
head = new_node;
}
// Utility function to print the linked list
public void printList(ListNode head)
{
ListNode temp = head;
while (temp != null)
{
Console.Write(temp.val + " ");
temp = temp.next;
}
}
// Driver Code
public static void Main(String[] args)
{
linkedList ll = new linkedList();
ll.Push(5);
ll.Push(0);
ll.Push(3);
ll.Push(1);
ll.Push(2);
// Function Call
ll.printList(ll.nextLargerLL(ll.head));
}
}
// This code is contributed by Amit Katiyar
输出:
3 3 5 5 0
时间复杂度: O(N)
辅助空间: O(N)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live