给定链表中的最长递增子序列
给定链表lis形式的数字序列。找出给定链表的最长递增子序列 (LIS) 的长度。
例子:
Input: list = 3->10->2->1->20
Output: 3
Explanation: The longest increasing subsequence is 3->10-> 20
Input: list = 3-> 2
Output: 1
Explanation: The longest increasing subsequence are 3 and 2
Input: list = 50->3->10->7->40->80
Output: Length of LIS = 4
Explanation: The longest increasing subsequence is {3->7->40->80} or {3->10->40->80}
方法:解决方案的基本直觉是从第一个节点开始迭代到链表的末尾。在移动的过程中计算在每个节点结束的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)