📜  给定链表中的最长递增子序列

📅  最后修改于: 2022-05-13 01:56:04.539000             🧑  作者: Mango

给定链表中的最长递增子序列

给定链表lis形式的数字序列。找出给定链表的最长递增子序列 (LIS) 的长度。

例子:

方法:解决方案的基本直觉是从第一个节点开始迭代到链表的末尾。在移动的过程中计算在每个节点结束的LIS的长度并将其存储在一个计数变量中。最后,计算所有节点之间的最大计数值。请按照以下步骤解决问题:

  • 从起始节点开始遍历链表。
    • 具有一个节点的链表的LIS长度为1 。因此我们将每个节点计数变量初始化为1
    • 对于每个第 i 个节点,遍历第一个(i-1)个节点并执行以下操作:
      • 如果当前节点的值大于前一个节点的值,则扩展序列长度
      • 由于需要以当前节点结尾的最大长度。从满足先前条件的前(i-1)个节点中选择节点 并具有最大计数值。
  • 一旦按照上述过程遍历所有节点。找到所有节点中的最大计数值
  • 最大计数值是LIS所需的长度。

下面是上述方法的实现:

C++
// C++ program to find LIS on LinkedList
#include 
using namespace std;
 
// Structure of a node
class Node {
public:
    int data;
    struct Node* next;
 
    // "count" variable is to keep track
    // of LIS_LENGTH ending with
    // that particular element
    int count;
};
 
// Function to find the length of the LIS
int LIS(struct Node* head)
{
    // If linked list is empty length is 0
    if (head == NULL)
        return 0;
 
    // If linked list has only one node
    // LIS length is 1
    if (head->next == NULL)
        return 1;
    Node* curr_p = head->next;
 
    // This loop calculates what is
    // LIS_LENGTH ending with each and
    // every node and stores in
    // curr->count variable
    while (curr_p != NULL) {
        int maxi = 0;
        Node* prev_p = head;
 
        // This while loop traverse all nodes
        // before curr_p and finds which node
        // to extend so that maximum LIS
        // length ending with curr_P can be
        while (prev_p != curr_p) {
 
            // Only extend if present data
            // greater than previous value
            if (curr_p->data
                > prev_p->data) {
                if (prev_p->count > maxi) {
                    maxi = prev_p->count;
                }
            }
            prev_p = prev_p->next;
        }
        curr_p->count = 1 + maxi;
        curr_p = curr_p->next;
    }
    int LIS_length = 0;
    curr_p = head;
 
    // Finding Maximum LIS_LENGTH
    while (curr_p != NULL) {
        if (LIS_length < curr_p->count) {
            LIS_length = curr_p->count;
        }
        curr_p = curr_p->next;
    }
    return LIS_length;
}
 
// Function to push a node in linked list
void push(struct Node** head_ref,
          int new_data)
{
    // Allocate node
    Node* new_node = new Node();
 
    // Put in the data
    new_node->data = new_data;
 
    // Link the old list with the new node
    new_node->next = (*head_ref);
 
    // Assign count value to 1
    new_node->count = 1;
 
    // Move the head to point the new node
    (*head_ref) = new_node;
}
 
// Driver code
int main()
{
    // Start with the empty list
    struct Node* head = NULL;
 
    // Create a linked list
    // Created linked list will be
    // 3->10->2->1->20
    push(&head, 20);
    push(&head, 1);
    push(&head, 2);
    push(&head, 10);
    push(&head, 3);
 
    // Call LIS function which calculates
    // LIS of Linked List
    int ans = LIS(head);
    cout << ans;
    return 0;
}


Java
// Java program to find LIS on LinkedList
 
import java.util.*;
 
class GFG{
 
// Structure of a node
static class Node {
    int data;
    Node next;
 
    // "count" variable is to keep track
    // of LIS_LENGTH ending with
    // that particular element
    int count;
};
 
// Function to find the length of the LIS
static int LIS(Node head)
{
    // If linked list is empty length is 0
    if (head == null)
        return 0;
 
    // If linked list has only one node
    // LIS length is 1
    if (head.next == null)
        return 1;
    Node curr_p = head.next;
 
    // This loop calculates what is
    // LIS_LENGTH ending with each and
    // every node and stores in
    // curr.count variable
    while (curr_p != null) {
        int maxi = 0;
        Node prev_p = head;
 
        // This while loop traverse all nodes
        // before curr_p and finds which node
        // to extend so that maximum LIS
        // length ending with curr_P can be
        while (prev_p != curr_p) {
 
            // Only extend if present data
            // greater than previous value
            if (curr_p.data
                > prev_p.data) {
                if (prev_p.count > maxi) {
                    maxi = prev_p.count;
                }
            }
            prev_p = prev_p.next;
        }
        curr_p.count = 1 + maxi;
        curr_p = curr_p.next;
    }
    int LIS_length = 0;
    curr_p = head;
 
    // Finding Maximum LIS_LENGTH
    while (curr_p != null) {
        if (LIS_length < curr_p.count) {
            LIS_length = curr_p.count;
        }
        curr_p = curr_p.next;
    }
    return LIS_length;
}
 
// Function to push a node in linked list
static Node push(Node head_ref,
          int new_data)
{
    // Allocate node
    Node new_node = new Node();
 
    // Put in the data
    new_node.data = new_data;
 
    // Link the old list with the new node
    new_node.next = head_ref;
 
    // Assign count value to 1
    new_node.count = 1;
 
    // Move the head to point the new node
    head_ref = new_node;
    return head_ref;
}
 
// Driver code
public static void main(String[] args)
{
    // Start with the empty list
    Node head = null;
 
    // Create a linked list
    // Created linked list will be
    // 3.10.2.1.20
    head = push(head, 20);
    head = push(head, 1);
    head = push(head, 2);
    head = push(head, 10);
    head = push(head, 3);
 
    // Call LIS function which calculates
    // LIS of Linked List
    int ans = LIS(head);
    System.out.print(ans);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python code for the above approach
 
# Structure of a node
class Node:
 
    def __init__(self, d):
        self.data = d
        self.next = None
        self.count = 1
 
    # "count" variable is to keep track
    # of LIS_LENGTH ending with
    # that particular element
 
# Function to find the length of the LIS
def LIS(head):
 
    # If linked list is empty length is 0
    if (head == None):
        return 0
 
    # If linked list has only one node
    # LIS length is 1
    if (head.next == None):
        return 1
    curr_p = head.next
 
    # This loop calculates what is
    # LIS_LENGTH ending with each and
    # every node and stores in
    # curr.count variable
    while (curr_p != None):
        maxi = 0
        prev_p = head
 
        # This while loop traverse all nodes
        # before curr_p and finds which node
        # to extend so that maximum LIS
        # length ending with curr_P can be
        while (prev_p != curr_p):
 
            # Only extend if present data
            # greater than previous value
            if (curr_p.data > prev_p.data):
                if (prev_p.count > maxi):
                    maxi = prev_p.count
            prev_p = prev_p.next
 
        curr_p.count = 1 + maxi
        curr_p = curr_p.next
 
    LIS_length = 0
    curr_p = head
 
    # Finding Maximum LIS_LENGTH
    while (curr_p != None):
        if (LIS_length < curr_p.count):
            LIS_length = curr_p.count
        curr_p = curr_p.next
 
    return LIS_length
 
# Driver code
 
# Start with the empty list
# Create a linked list
# Created linked list will be
# 3->10->2->1->20
head = Node(3)
head.next = Node(10)
head.next.next = Node(2)
head.next.next.next = Node(1)
head.next.next.next.next = Node(20)
 
# Call LIS function which calculates
# LIS of Linked List
ans = LIS(head)
print(ans)
 
# This code is contributed by Saurabh Jaiswal


C#
// C# program to find LIS on List
using System;
using System.Collections.Generic;
 
public class GFG {
 
  // Structure of a node
  public class Node {
    public int data;
    public Node next;
 
    // "count" variable is to keep track
    // of LIS_LENGTH ending with
    // that particular element
    public int count;
  };
 
  // Function to find the length of the LIS
  static int LIS(Node head)
  {
     
    // If linked list is empty length is 0
    if (head == null)
      return 0;
 
    // If linked list has only one node
    // LIS length is 1
    if (head.next == null)
      return 1;
    Node curr_p = head.next;
 
    // This loop calculates what is
    // LIS_LENGTH ending with each and
    // every node and stores in
    // curr.count variable
    while (curr_p != null) {
      int maxi = 0;
      Node prev_p = head;
 
      // This while loop traverse all nodes
      // before curr_p and finds which node
      // to extend so that maximum LIS
      // length ending with curr_P can be
      while (prev_p != curr_p) {
 
        // Only extend if present data
        // greater than previous value
        if (curr_p.data > prev_p.data) {
          if (prev_p.count > maxi) {
            maxi = prev_p.count;
          }
        }
        prev_p = prev_p.next;
      }
      curr_p.count = 1 + maxi;
      curr_p = curr_p.next;
    }
    int LIS_length = 0;
    curr_p = head;
 
    // Finding Maximum LIS_LENGTH
    while (curr_p != null) {
      if (LIS_length < curr_p.count) {
        LIS_length = curr_p.count;
      }
      curr_p = curr_p.next;
    }
    return LIS_length;
  }
 
  // Function to push a node in linked list
  static Node push(Node head_ref, int new_data)
  {
     
    // Allocate node
    Node new_node = new Node();
 
    // Put in the data
    new_node.data = new_data;
 
    // Link the old list with the new node
    new_node.next = head_ref;
 
    // Assign count value to 1
    new_node.count = 1;
 
    // Move the head to point the new node
    head_ref = new_node;
    return head_ref;
  }
 
  // Driver code
  public static void Main(String[] args)
  {
     
    // Start with the empty list
    Node head = null;
 
    // Create a linked list
    // Created linked list will be
    // 3.10.2.1.20
    head = push(head, 20);
    head = push(head, 1);
    head = push(head, 2);
    head = push(head, 10);
    head = push(head, 3);
 
    // Call LIS function which calculates
    // LIS of Linked List
    int ans = LIS(head);
    Console.Write(ans);
  }
}
 
// This code is contributed by Rajput-Ji


Javascript



输出
3

时间复杂度: O(N * N) 其中 N 是链表的长度
辅助空间: O(N)