📜  链表中的下一个更大的元素

📅  最后修改于: 2021-09-02 07:36:00             🧑  作者: Mango

给定一个整数链表L ,任务是返回一个整数链表,使得它包含给定链表中每个元素的下一个更大的元素。如果任何元素都没有更大的元素,则为其插入0

例子:

朴素的方法:朴素的方法是遍历链表L ,对于链表中的每个元素,通过从当前元素遍历整个字符串来查找列表中的下一个更大的元素。

时间复杂度: O(N 2 )

高效的方法:可以通过维护一个单调递减的元素堆栈来优化上述朴素的方法。如果找到更大的元素,则将其追加到结果链表L’ 中,否则追加0 。以下是步骤:

  1. 将第一个节点压入堆栈。
  2. 一个接一个地选择节点的其余部分,并在循环中执行以下步骤:
    • 将当前节点标记为下一个节点。
    • 如果堆栈不为空,则将堆栈的顶部节点值与下一个节点值进行比较。
    • 如果下一个节点值大于顶节点值,则从堆栈中弹出顶节点,下一个是弹出节点的下一个更大的元素。
    • 当弹出的节点值小于下一个节点值时,继续从堆栈中弹出节点。下一个节点将成为所有此类弹出节点的下一个更大的元素。
  3. 最后,压入堆栈中的下一个节点。
  4. 步骤 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