使用 O(1) 额外空间查找链表中最长回文列表长度的 C++ 程序
给定一个链表,找出该链表中存在的最长回文链表的长度。
例子:
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 common 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;
}
输出 :
5
时间复杂度: O(n 2 )
请注意,上面的代码修改了给定的链表,如果不允许修改链表,则可能无法正常工作。然而,我们终于可以再做一次逆向来获取原始列表。
有关更多详细信息,请参阅有关使用 O(1) 额外空间的链表中最长回文列表的长度的完整文章!