📌  相关文章
📜  使用 O(1) 额外空间的链表中最长回文列表的长度

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

使用 O(1) 额外空间的链表中最长回文列表的长度

给定一个链表,找出该链表中存在的最长回文列表的长度。
例子:

Input  : List = 2->3->7->3->2->12->24
Output : 5
The longest palindrome list is 2->3->7->3->2

Input  : List = 12->4->4->3->14
Output : 2
The longest palindrome list is 4->4

一个简单的解决方案可能是将链表内容复制到数组,然后找到数组中最长的回文子数组,但这种解决方案是不允许的,因为它需要额外的空间。
该想法基于迭代链表反向过程。我们遍历给定的链表,并从左边一个一个地反转链表的每个前缀。反转前缀后,我们找到从反转前缀开始的最长公共列表和反转前缀之后的列表。
下面是上述想法的实现。

C++
// C++ program to find longest palindrome
// sublist in a list in O(1) time.
#include
using namespace std;
 
//structure of the linked list
struct Node
{
    int data;
    struct Node* next;
};
 
// function for counting the common elements
int countCommon(Node *a, Node *b)
{
    int count = 0;
 
    // loop to count coomon in the list starting
    // from node a and b
    for (; a && b; a = a->next, b = b->next)
 
        // increment the count for same values
        if (a->data == b->data)
            ++count;
        else
            break;
 
    return count;
}
 
// Returns length of the longest palindrome
// sublist in given list
int maxPalindrome(Node *head)
{
    int result = 0;
    Node *prev = NULL, *curr = head;
 
    // loop till the end of the linked list
    while (curr)
    {
        // The sublist from head to current
        // reversed.
        Node *next = curr->next;
        curr->next = prev;
 
        // check for odd length palindrome
        // by finding longest common list elements
        // beginning from prev and from next (We
        // exclude curr)
        result = max(result,
                     2*countCommon(prev, next)+1);
 
        // check for even length palindrome
        // by finding longest common list elements
        // beginning from curr and from next
        result = max(result,
                     2*countCommon(curr, next));
 
        // update prev and curr for next iteration
        prev = curr;
        curr = next;
    }
    return result;
}
 
// Utility function to create a new list node
Node *newNode(int key)
{
    Node *temp = new Node;
    temp->data = key;
    temp->next = NULL;
    return temp;
}
 
/* Driver program to test above functions*/
int main()
{
    /* Let us create a linked lists to test
       the functions
    Created list is a: 2->4->3->4->2->15 */
    Node *head = newNode(2);
    head->next = newNode(4);
    head->next->next = newNode(3);
    head->next->next->next = newNode(4);
    head->next->next->next->next = newNode(2);
    head->next->next->next->next->next = newNode(15);
 
    cout << maxPalindrome(head) << endl;
    return 0;
}


Java
// Java program to find longest palindrome
// sublist in a list in O(1) time.
class GfG
{
 
//structure of the linked list
static class Node
{
    int data;
    Node next;
}
 
// function for counting the common elements
static int countCommon(Node a, Node b)
{
    int count = 0;
 
    // loop to count coomon in the list starting
    // from node a and b
    for (; a != null && b != null;
            a = a.next, b = b.next)
 
        // increment the count for same values
        if (a.data == b.data)
            ++count;
        else
            break;
 
    return count;
}
 
// Returns length of the longest palindrome
// sublist in given list
static int maxPalindrome(Node head)
{
    int result = 0;
    Node prev = null, curr = head;
 
    // loop till the end of the linked list
    while (curr != null)
    {
        // The sublist from head to current
        // reversed.
        Node next = curr.next;
        curr.next = prev;
 
        // check for odd length
        // palindrome by finding
        // longest common list elements
        // beginning from prev and
        // from next (We exclude curr)
        result = Math.max(result,
                    2 * countCommon(prev, next)+1);
 
        // check for even length palindrome
        // by finding longest common list elements
        // beginning from curr and from next
        result = Math.max(result,
                    2*countCommon(curr, next));
 
        // update prev and curr for next iteration
        prev = curr;
        curr = next;
    }
    return result;
}
 
// Utility function to create a new list node
static Node newNode(int key)
{
    Node temp = new Node();
    temp.data = key;
    temp.next = null;
    return temp;
}
 
/* Driver code*/
public static void main(String[] args)
{
    /* Let us create a linked lists to test
    the functions
    Created list is a: 2->4->3->4->2->15 */
    Node head = newNode(2);
    head.next = newNode(4);
    head.next.next = newNode(3);
    head.next.next.next = newNode(4);
    head.next.next.next.next = newNode(2);
    head.next.next.next.next.next = newNode(15);
 
    System.out.println(maxPalindrome(head));
}
}
 
// This code is contributed by
// Prerna Saini.


Python
# Python program to find longest palindrome
# sublist in a list in O(1) time.
 
# Linked List node
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
 
# function for counting the common elements
def countCommon(a, b) :
 
    count = 0
 
    # loop to count coomon in the list starting
    # from node a and b
    while ( a != None and b != None ) :
 
        # increment the count for same values
        if (a.data == b.data) :
            count = count + 1
        else:
            break
         
        a = a.next
        b = b.next
 
    return count
 
# Returns length of the longest palindrome
# sublist in given list
def maxPalindrome(head) :
 
    result = 0
    prev = None
    curr = head
 
    # loop till the end of the linked list
    while (curr != None) :
     
        # The sublist from head to current
        # reversed.
        next = curr.next
        curr.next = prev
 
        # check for odd length
        # palindrome by finding
        # longest common list elements
        # beginning from prev and
        # from next (We exclude curr)
        result = max(result,
                    2 * countCommon(prev, next) + 1)
 
        # check for even length palindrome
        # by finding longest common list elements
        # beginning from curr and from next
        result = max(result,
                    2 * countCommon(curr, next))
 
        # update prev and curr for next iteration
        prev = curr
        curr = next
     
    return result
 
# Utility function to create a new list node
def newNode(key) :
 
    temp = Node(0)
    temp.data = key
    temp.next = None
    return temp
 
# Driver code
 
# Let us create a linked lists to test
# the functions
# Created list is a: 2->4->3->4->2->15
head = newNode(2)
head.next = newNode(4)
head.next.next = newNode(3)
head.next.next.next = newNode(4)
head.next.next.next.next = newNode(2)
head.next.next.next.next.next = newNode(15)
 
print(maxPalindrome(head))
 
# This code is contributed by Arnab Kundu


C#
// C# program to find longest palindrome
// sublist in a list in O(1) time.
using System;
 
class GfG
{
 
//structure of the linked list
public class Node
{
    public int data;
    public Node next;
}
 
// function for counting the common elements
static int countCommon(Node a, Node b)
{
    int count = 0;
 
    // loop to count coomon in the list starting
    // from node a and b
    for (; a != null && b != null;
            a = a.next, b = b.next)
 
        // increment the count for same values
        if (a.data == b.data)
            ++count;
        else
            break;
 
    return count;
}
 
// Returns length of the longest palindrome
// sublist in given list
static int maxPalindrome(Node head)
{
    int result = 0;
    Node prev = null, curr = head;
 
    // loop till the end of the linked list
    while (curr != null)
    {
        // The sublist from head to current
        // reversed.
        Node next = curr.next;
        curr.next = prev;
 
        // check for odd length
        // palindrome by finding
        // longest common list elements
        // beginning from prev and
        // from next (We exclude curr)
        result = Math.Max(result,
                    2 * countCommon(prev, next)+1);
 
        // check for even length palindrome
        // by finding longest common list elements
        // beginning from curr and from next
        result = Math.Max(result,
                    2*countCommon(curr, next));
 
        // update prev and curr for next iteration
        prev = curr;
        curr = next;
    }
    return result;
}
 
// Utility function to create a new list node
static Node newNode(int key)
{
    Node temp = new Node();
    temp.data = key;
    temp.next = null;
    return temp;
}
 
/* Driver code*/
public static void Main(String []args)
{
    /* Let us create a linked lists to test
    the functions
    Created list is a: 2->4->3->4->2->15 */
    Node head = newNode(2);
    head.next = newNode(4);
    head.next.next = newNode(3);
    head.next.next.next = newNode(4);
    head.next.next.next.next = newNode(2);
    head.next.next.next.next.next = newNode(15);
 
    Console.WriteLine(maxPalindrome(head));
}
}
 
// This code is contributed by Arnab Kundu


Javascript


输出 :

5

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程