检查两个循环链表是否相同
给定两个循环链表L1和L2 ,任务是找出这两个循环链表是否相同。
注意:任何链表的头指向各自链表的任何节点,并且链表可以包含重复的元素。
例子:
Input: L1: 1 -> 2 -> 3 -> 4 -> 5 -> 1 -> 2 -> 6
L2: 5 -> 1 -> 2 -> 6 -> 1 -> 2 -> 3 -> 4
Output: Yes
Explanation: If checked the 5th element of L1 and 1st element of L2 then they are identical.
As they are circular, does not matter from where we start checking.
Input: L1: 1 -> 2 -> 3
L2: 1 ->3 -> 2
Output: No
方法:可以通过使用以下思想遍历循环链表来解决该问题:
Fix the starting point of any list. Now consider every element of the other list as head and compare if both the lists are identical or not for that starting point.
请按照以下步骤解决问题:
- 分别计算两个循环链表的长度l1和l2
- 如果两个长度不同,则返回false
- 初始化计数= 0 ,标志=假
- 为head1初始化临时指针h1和h2 (l1 的起始指针) 和head2 (l2 的起始指针)
- 遍历而不返回布尔值,true 或 false:
- 如果 h1 的数据等于 h2 的数据,则将 h1 和 h2 移动到其下一个节点并将计数增加 1。
- 如果 Count 等于l1 (或l2 ),则链表相同,返回true
- 否则,将指针h1和变量count重置为其初始状态。
- 如果,flag == 1,则返回false ,因为这意味着完成了一轮,现在如果元素不匹配,则列表不能相同。
- 如果h2->next = head2则旋转一圈完成,然后设置flag = 1
- 将h2指针移动1 个位置, h2 = h2->next 。
下面是上述方法的实现:
C++
// C++ program to Check that two circular
// linked list are identical or not
#include
using namespace std;
// Circular Linked list Node Class
class Node {
public:
int data;
Node* next;
// Constructor function
Node(int data)
{
this->data = data;
this->next = NULL;
}
};
// Function to insert a node in
// tail in circular linked list
void insertNode(Node*& head,
Node*& tail, int d)
{
// First insertion in circular
// linked list
if (head == NULL) {
Node* newNode = new Node(d);
head = newNode;
tail = newNode;
newNode->next = newNode;
}
else {
// Non-empty list
Node* temp = new Node(d);
temp->next = tail->next;
tail->next = temp;
tail = tail->next;
}
}
// Function to print circular linked list
void print(Node* head)
{
Node* curr = head;
// If circular linked list is empty
if (head == NULL) {
cout << "List is Empty " << endl;
return;
}
// Else iterate until node is NOT head
do {
cout << curr->data << " ";
curr = curr->next;
} while (curr != head);
cout << endl;
}
// Function to return length of
// circular linked list
int length(Node* head)
{
// If circular linked list is empty
if (head == NULL) {
return 0;
}
int size = 0;
Node* curr = head;
// Else iterate until node is NOT head
do {
curr = curr->next;
size++;
} while (curr != head);
return size;
}
// Function to Check that two circular
// linked list are identical or not
bool checkIdentical(Node*& head1,
Node*& head2)
{
// Get the length of first linked list
int l1 = length(head1);
// Get the length of first linked list
int l2 = length(head2);
// If l1!=l2 then linked list can not
// be identical
if (l1 != l2)
return false;
// Initialize the variables
int Count = 0;
bool flag = 0;
// Initialize temporary pointers
Node* h1 = head1;
Node* h2 = head2;
// Traverse the list
while (1) {
// If element matches in two
// circular linked list
if (h1->data == h2->data) {
h1 = h1->next;
Count++;
// If count equals to l1(or l2)
// then linked list are identical
if (Count == l1)
return true;
}
// If element does not matches
// in two circular linked list
else {
h1 = head1;
Count = 0;
// If flag becomes 1 then one
// rotation is complete and
// if now data does not match then
// linked lists are not identical
if (flag)
return false;
}
// Check if h2 complete one rotation
if (h2->next == head2)
flag = 1;
// Move h2 to h2->next
h2 = h2->next;
}
}
// Driver Code
int main()
{
Node* head1 = NULL;
Node* tail1 = NULL;
insertNode(head1, tail1, 1);
insertNode(head1, tail1, 2);
insertNode(head1, tail1, 3);
insertNode(head1, tail1, 4);
insertNode(head1, tail1, 5);
insertNode(head1, tail1, 1);
insertNode(head1, tail1, 2);
insertNode(head1, tail1, 6);
Node* head2 = NULL;
Node* tail2 = NULL;
insertNode(head2, tail2, 5);
insertNode(head2, tail2, 1);
insertNode(head2, tail2, 2);
insertNode(head2, tail2, 6);
insertNode(head2, tail2, 1);
insertNode(head2, tail2, 2);
insertNode(head2, tail2, 3);
insertNode(head2, tail2, 4);
bool flag = checkIdentical(head1, head2);
if (flag)
cout << "Yes";
else
cout << "No";
return 0;
}
Yes
时间复杂度:O(N)
辅助空间:O(1)