两个链表的最长公共后缀
给定两个单链表,求两个链表的最长公共后缀。如果没有作为后缀的公共字符,则返回两个链表的最小长度。
例子:
Input : list1 = w -> a -> l -> k -> i -> n -> g
list2 = l -> i -> s -> t -> e -> n -> i -> n -> g
Output :i -> n -> g
Input : list1 = p -> a -> r -> t -> y
list2 = p -> a -> r -> t -> y -> i -> n -> g
Output :p -> a -> r -> t -> y
一个简单的解决方案是使用辅助数组来存储链表。然后打印两个数组的最长公共后缀。
上述解决方案需要额外的空间。我们可以通过首先对两个链表进行反向操作来节省空间。逆向后,我们可以很容易地找到最长公共前缀的长度。再次倒车以取回原始列表。
这里重要的一点是元素的顺序。我们需要打印从第 n 到结束的节点。我们使用两个指针方法按要求的顺序使用上面找到的计数和打印节点。
C++
// C++ program to find the Longest Common
// suffix in linked lists
#include
using namespace std;
/* Linked list node */
struct Node
{
char data;
struct Node* next;
};
/* Function to insert a node at the beginning of
the linked list */
void push(struct Node **head_ref, int new_data)
{
struct Node* new_node = new Node;
new_node->data = new_data;
new_node->next = *head_ref;
*head_ref = new_node;
}
/* Function to reverse the linked list */
struct Node *reverseList(struct Node *head_ref)
{
struct Node *current, *prev, *next;
current = head_ref;
prev = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
// Utility function to print last n nodes
void printLastNNode(struct Node* head, int n)
{
// if n == 0
if (n <= 0)
return;
// Move reference pointer n positions ahead
struct Node* ref_ptr = head;
while (ref_ptr != NULL && n--)
ref_ptr = ref_ptr->next;
// Now move main and reference pointers at
// same speed. By the end of this loop,
// reference pointer would point to end and
// main pointer would point to n-th node
// from end.
Node *main_ptr = head;
while (ref_ptr != NULL) {
main_ptr = main_ptr->next;
ref_ptr = ref_ptr->next;
}
// Print last n nodes.
while (main_ptr != NULL)
{
cout << main_ptr->data;
main_ptr = main_ptr->next;
}
}
// Prints the Longest Common suffix in
// linked lists
void longestCommSuffix(Node *h1, Node *h2)
{
// Reverse Both Linked list
h1 = reverseList(h1);
h2 = reverseList(h2);
// Now we print common nodes from head
Node *temp1 = h1, *temp2 = h2;
int count = 0;
while (temp1!=NULL&&temp2!=NULL)
{
// If a node is not common, break
if (temp1 -> data != temp2 -> data)
break;
// Keep printing while there are
// common nodes.
count++;
temp1 = temp1 -> next;
temp2 = temp2 -> next;
}
// Reversing linked lists to retain
// original lists.
h1 = reverseList(h1);
h2 = reverseList(h2);
printLastNNode(h1, count);
}
// Driver program to test above
int main()
{
struct Node *h1 = NULL, *h2 = NULL;
// creating the 1 linked list
push(&h1,'g');
push(&h1,'n');
push(&h1,'i');
push(&h1,'k');
push(&h1,'l');
push(&h1,'a');
push(&h1,'w');
// creating the 2 linked list
push(&h2,'g');
push(&h2,'n');
push(&h2,'i');
push(&h2,'n');
push(&h2,'e');
push(&h2,'t');
push(&h2,'s');
push(&h2,'i');
push(&h2,'l');
longestCommSuffix(h1, h2);
return 0;
}
Java
// Java program to find the Longest Common
// suffix in linked lists
import java.util.*;
class GFG
{
/* Linked list node */
static class Node
{
int data;
Node next;
};
static Node h1,h2;
/* Function to insert a node at the beginning
of the linked list */
static Node push(Node head_ref, int new_data)
{
Node new_node = new Node();
new_node.data = new_data;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
/* Function to reverse the linked list */
static Node reverseList(Node head_ref)
{
Node current, prev, next;
current = head_ref;
prev = null;
while (current != null)
{
next = current.next;
current.next = prev;
prev = current;
current = next;
}
return prev;
}
// Utility function to print last n nodes
static void printLastNNode(Node head, int n)
{
// if n == 0
if (n <= 0)
return;
// Move reference pointer n positions ahead
Node ref_ptr = head;
while (ref_ptr != null && n-- > 0)
ref_ptr = ref_ptr.next;
// Now move main and reference pointers at
// same speed. By the end of this loop,
// reference pointer would point to end and
// main pointer would point to n-th node
// from end.
Node main_ptr = head;
while (ref_ptr != null)
{
main_ptr = main_ptr.next;
ref_ptr = ref_ptr.next;
}
// Print last n nodes.
while (main_ptr != null)
{
System.out.print((char)(main_ptr.data));
main_ptr = main_ptr.next;
}
}
// Prints the Longest Common suffix in
// linked lists
static void longestCommSuffix()
{
// Reverse Both Linked list
h1 = reverseList(h1);
h2 = reverseList(h2);
// Now we print common nodes from head
Node temp1 = h1, temp2 = h2;
int count = 0;
while (temp1 != null && temp2 != null)
{
// If a node is not common, break
if (temp1 . data != temp2 . data)
break;
// Keep printing while there are
// common nodes.
count++;
temp1 = temp1 . next;
temp2 = temp2 . next;
}
// Reversing linked lists to retain
// original lists.
h1 = reverseList(h1);
h2 = reverseList(h2);
printLastNNode(h1, count);
}
// Driver Code
public static void main(String[] args)
{
h1 = null; h2 = null;
// creating the 1 linked list
h1 = push(h1, 'g');
h1 = push(h1, 'n');
h1 = push(h1, 'i');
h1 = push(h1, 'k');
h1 = push(h1, 'l');
h1 = push(h1, 'a');
h1 = push(h1, 'w');
// creating the 2 linked list
h2 = push(h2, 'g');
h2 = push(h2, 'n');
h2 = push(h2, 'i');
h2 = push(h2, 'n');
h2 = push(h2, 'e');
h2 = push(h2, 't');
h2 = push(h2, 's');
h2 = push(h2, 'i');
h2 = push(h2, 'l');
longestCommSuffix();
}
}
// This code is contributed by Rajput-Ji
Python3
# Python3 program to find the Longest Common
# suffix in linked lists
# Link list node
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Function to insert a node at the
# beginning of the linked list
def push( head_ref, new_data):
new_node = Node(new_data)
new_node.next = head_ref
head_ref = new_node
return head_ref
# Function to reverse the linked list
def reverseList(head_ref):
next = None
current = head_ref
prev = None
while (current != None):
next = current.next
current.next = prev
prev = current
current = next
return prev
# Utility function to print last n nodes
def printLastNNode(head, n):
# If n == 0
if (n <= 0):
return
# Move reference pointer n positions ahead
ref_ptr = head
while (ref_ptr != None and n != 0):
n -= 1
ref_ptr = ref_ptr.next
# Now move main and reference pointers at
# same speed. By the end of this loop,
# reference pointer would point to end and
# main pointer would point to n-th node
# from end.
main_ptr = head
while (ref_ptr != None):
main_ptr = main_ptr.next
ref_ptr = ref_ptr.next
# Print last n nodes.
while (main_ptr != None):
print(main_ptr.data, end = '')
main_ptr = main_ptr.next
# Prints the Longest Common suffix in
# linked lists
def longestCommSuffix(h1, h2):
# Reverse Both Linked list
h1 = reverseList(h1)
h2 = reverseList(h2)
# Now we print common nodes from head
temp1 = h1
temp2 = h2
count = 0
while (temp1 != None and temp2 != None):
# If a node is not common, break
if (temp1.data != temp2.data):
break
# Keep printing while there are
# common nodes.
count += 1
temp1 = temp1.next
temp2 = temp2.next
# Reversing linked lists to retain
# original lists.
h1 = reverseList(h1)
h2 = reverseList(h2)
printLastNNode(h1, count)
# Driver code
if __name__=='__main__':
h1 = None
h2 = None
# Creating the 1 linked list
h1 = push(h1, 'g')
h1 = push(h1, 'n')
h1 = push(h1, 'i')
h1 = push(h1, 'k')
h1 = push(h1, 'l')
h1 = push(h1, 'a')
h1 = push(h1, 'w')
# Creating the 2 linked list
h2 = push(h2, 'g')
h2 = push(h2, 'n')
h2 = push(h2, 'i')
h2 = push(h2, 'n')
h2 = push(h2, 'e')
h2 = push(h2, 't')
h2 = push(h2, 's')
h2 = push(h2, 'i')
h2 = push(h2, 'l')
longestCommSuffix(h1, h2)
# This code is contributed by rutvik_56
C#
// C# program to find the Longest Common
// suffix in linked lists
using System;
class GFG
{
/* Linked list node */
public class Node
{
public int data;
public Node next;
};
static Node h1, h2;
/* Function to insert a node
at the beginning of the linked list */
static Node push(Node head_ref,
int new_data)
{
Node new_node = new Node();
new_node.data = new_data;
new_node.next = head_ref;
head_ref = new_node;
return head_ref;
}
/* Function to reverse the linked list */
static Node reverseList(Node head_ref)
{
Node current, prev, next;
current = head_ref;
prev = null;
while (current != null)
{
next = current.next;
current.next = prev;
prev = current;
current = next;
}
return prev;
}
// Utility function to print last n nodes
static void printLastNNode(Node head, int n)
{
// if n == 0
if (n <= 0)
return;
// Move reference pointer n positions ahead
Node ref_ptr = head;
while (ref_ptr != null && n-- > 0)
ref_ptr = ref_ptr.next;
// Now move main and reference pointers at
// same speed. By the end of this loop,
// reference pointer would point to end and
// main pointer would point to n-th node
// from end.
Node main_ptr = head;
while (ref_ptr != null)
{
main_ptr = main_ptr.next;
ref_ptr = ref_ptr.next;
}
// Print last n nodes.
while (main_ptr != null)
{
Console.Write((char)(main_ptr.data));
main_ptr = main_ptr.next;
}
}
// Prints the Longest Common suffix in
// linked lists
static void longestCommSuffix()
{
// Reverse Both Linked list
h1 = reverseList(h1);
h2 = reverseList(h2);
// Now we print common nodes from head
Node temp1 = h1, temp2 = h2;
int count = 0;
while (temp1 != null && temp2 != null)
{
// If a node is not common, break
if (temp1 . data != temp2 . data)
break;
// Keep printing while there are
// common nodes.
count++;
temp1 = temp1 . next;
temp2 = temp2 . next;
}
// Reversing linked lists to retain
// original lists.
h1 = reverseList(h1);
h2 = reverseList(h2);
printLastNNode(h1, count);
}
// Driver Code
public static void Main(String[] args)
{
h1 = null; h2 = null;
// creating the 1 linked list
h1 = push(h1, 'g');
h1 = push(h1, 'n');
h1 = push(h1, 'i');
h1 = push(h1, 'k');
h1 = push(h1, 'l');
h1 = push(h1, 'a');
h1 = push(h1, 'w');
// creating the 2 linked list
h2 = push(h2, 'g');
h2 = push(h2, 'n');
h2 = push(h2, 'i');
h2 = push(h2, 'n');
h2 = push(h2, 'e');
h2 = push(h2, 't');
h2 = push(h2, 's');
h2 = push(h2, 'i');
h2 = push(h2, 'l');
longestCommSuffix();
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
ing
时间复杂度:O(N)