给定双向链表“ L”和对双向链表“ L”的节点的引用数组“ refArr”。数组’refArr’不包含任何重复的引用,并且这些引用不是ORDERED 。
m <=总编号双链列表中的节点数,其中m =参考数组的大小。
任务是在链接列表“ L”中找到已连接组件的总数。
链接列表“ L”中的“连接组件”定义为列表中的一组节点,它们的引用存储在数组“ refArr”中,并且在列表中彼此相邻。
例子:
Input: L = 5 <-> 2 <-> 10 <-> 1 <-> 3, refArr[] = {5, 10, 3, 1}
Output: 2
Two connected components are 5 and 10 <-> 1 <-> 3.
Since 2 is not included in the reference array, that makes 5 disconnected from the rest of the elements.
Input: L = 1 <-> 7 <-> 10 <-> 5 <-> 4 <-> 2, refArr[] = {5, 2, 7, 1}
Output: Total number of connected components are 3
解释:
Let us take a double linked list ‘L’ as { N1 N2 N3 N4 N5 N6 }
and the array ‘refArr’ as [ref_to_nodeN1, ref_to_nodeN4, ref_to_nodeN6, ref_to_nodeN2].
Output :
This set of array ‘refArr’ and linked list ‘L’ contains 3 connected components, which are { [N1, N2], [N4], [N6] } .
It is because references of the nodes N1 and N2 are present in the array ‘refArr’ and they are adjacent to each other in the list ‘L’ whereas N4 and N6 are not adjacent to N1, N2 or to each other. Hence, they form separate components.
Now, let the array ‘refArr’ be modified as [ref_to_nodeN4, ref_to_nodeN6, ref_to_nodeN5].
Output :
This set of array ‘refArr’ and linked list ‘L’ contains 1 connected component, which is { [N4, N5, N6] } .
It is because references of the nodes N4, N5 and N6 are present in the array ‘refArr’ and they are adjacent to each other in the list ‘L’. So, we together form 1 connected component.
天真的方法:涉及遍历喜欢列表“ L”的每个节点的数组“ refArr”,并检查该元素是否存在于数组中。同样,维护一个布尔变量,该变量跟踪链接列表中的前一个节点是否在数组中。取变量“ cc”,将其初始化为0并表示否。链表中已连接组件的数量。
现在,让我们考虑遍历时发生的多种情况:
- 情况1:如果前一个节点在数组中,并且当前遍历的当前节点也在数组中,则布尔变量将保持为1,表示当前节点在数组中,但由于当前节点而不会增加变量“ cc”构成上一个节点已经存在的组件的一部分。
- 情况2:如果前一个节点不在数组中,而当前遍历的节点在数组中,则将布尔变量更新为“ 1”,表示当前节点在数组中,并将变量cc递增1,因为当前节点构成一个新组件。
- 情况3:如果前一个节点在数组中,而当前遍历的节点不在数组中,则将布尔变量更新为0,表示当前节点不在数组中,并且不递增变量“ cc”因为当前节点不是任何组件的一部分。
- 情况4:如果前一个节点不在数组中,而当前遍历的节点也不在数组中,则布尔变量将保持为0,表示当前节点不在数组中,并且不对变量cc进行递增,因为当前节点不属于任何组件。
现在,在执行4种情况之一之后,移至链接列表中的下一个节点,并对该节点也执行相同的操作。
时间复杂度: O(n * m),其中n =链表’L’的大小。m =参考数组’refArr’的大小。
空间复杂度:O(1)
更好的方法:这种方法涉及unordered_set的使用。使用变量“ connectedComponents”,该变量初始化为0。connectedComponents表示链表中已连接组件的数量。
现在,对于引用数组’refArr’中的每个元素:
- 将存储在数组中的引用添加到unordered_set’refSet’。
-
- 如果同时存在上一个和下一个同级,则将变量“ connectedComponents”减1,这意味着我们已经缩小了两个组件之间的间隙,因此我们必须减少不正确计数的组件。
- 如果该集中只有前一个和下一个同级中的一个,则不会对no进行任何更新。组件。
- 如果集合中没有上一个和下一个同级,则我们必须增加不正确计数的组件,因为现在,当前节点形成了一个新组件。
下面是上述方法的实现:
CPP
// A C++ program to find number
// of Connected Components in a doubly linked list.
#include
using namespace std;
// Node of the doubly linked list
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
// Function to find number of connected
// components using a doubly linked list
// and a reference array
int func_connComp(struct Node** head_ref,
vector refArr, int n)
{
// Base case when the doubly
// linked list is empty
if (head_ref == NULL) {
return 0;
}
// Initialise connectedComponents to zero
int connectedComponents = 0;
// Initialise an unordered set
unordered_set refSet;
// Push the first element of the
// refArr in the refSet and
// set the connectedComponents to 1
refSet.insert(refArr[0]);
connectedComponents++;
// Loop over all the elements of the refArr
for (int i = 1; i < n; i++) {
// insert each reference node to the refSet
refSet.insert(refArr[i]);
// If the reference node is the head of the linked list
if (refArr[i]->prev == NULL) {
// when next sibling of the head node is
// not in the refSet
if (refSet.find(refArr[i]->next) == refSet.end()) {
connectedComponents++;
}
}
// If the reference node is the
// last node of the linked list*/
else if (refArr[i]->next == NULL) {
// when previous sibling of the
// node is not in the refSet
if (refSet.find(refArr[i]->next) == refSet.end()) {
connectedComponents++;
}
}
// the case when both previous and
// next siblings of the current node
// are in the refSet
else if (refSet.find(refArr[i]->prev) != refSet.end()
&& refSet.find(refArr[i]->next) != refSet.end()) {
connectedComponents--;
}
/*the case when previous and next
// siblings of the current node
// are not in the refSet*/
else if (refSet.find(refArr[i]->prev) == refSet.end()
&& refSet.find(refArr[i]->next) == refSet.end()) {
connectedComponents++;
}
}
return connectedComponents;
}
// Function to insert a node at the
// beginging of the Doubly Linked List
Node* push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node = new Node;
struct Node* current_node = new_node;
/* put in the data */
new_node->data = new_data;
/* since we are adding at the beginning,
prev is always NULL */
new_node->prev = NULL;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* change prev of head node to new node */
if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
/* move the head to point to the new node */
(*head_ref) = new_node;
return current_node;
}
// Function to print nodes in a given
// doubly linked list
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
// Driver code
int main()
{
// Start with the empty list
struct Node* head = NULL;
// Let us create a linked list to test
// the functions so as to find number
// of Connected Components Created a
// doubly linked list: 1 <-> 7 <-> 10 <-> 5 <-> 4 <-> 2
struct Node* ref_to_nodeN2 = push(&head, 2);
struct Node* ref_to_nodeN4 = push(&head, 4);
struct Node* ref_to_nodeN5 = push(&head, 5);
struct Node* ref_to_nodeN10 = push(&head, 10);
struct Node* ref_to_nodeN7 = push(&head, 7);
struct Node* ref_to_nodeN1 = push(&head, 1);
vector refArr{ ref_to_nodeN5,
ref_to_nodeN2, ref_to_nodeN7, ref_to_nodeN1 };
// This function will return the number
// of connected components of doubly linked list
int connectedComponents = func_connComp(&head, refArr, 4);
cout << "Total number of connected components are "
<< connectedComponents << endl;
return 0;
}
Python3
# A Python3 program to find number
# of Connected Components in a doubly linked list.
# Node of the doubly linked list
class Node:
def __init__(self):
self.data = 0
self.next = None
self.prev = None
# Function to find number of connected
# components using a doubly linked list
# and a reference array
def func_connComp(head_ref, refArr, n):
# Base case when the doubly
# linked list is empty
if (head_ref == None):
return 0;
# Initialise connectedComponents to zero
connectedComponents = 0;
# Initialise an unordered set
refSet = set()
# Push the first element of the
# refArr in the refSet and
# set the connectedComponents to 1
refSet.add(refArr[0]);
connectedComponents += 1
# Loop over all the elements of the refArr
for i in range(1, n):
# add each reference node to the refSet
refSet.add(refArr[i]);
# If the reference node is the head of the linked list
if (refArr[i].prev == None):
# when next sibling of the head node is
# not in the refSet
if (refArr[i].next not in refSet):
connectedComponents += 1
# If the reference node is the
# last node of the linked list'''
elif (refArr[i].next == None):
# when previous sibling of the
# node is not in the refSet
if (refArr[i].next not in refSet):
connectedComponents += 1
# the case when both previous and
# next siblings of the current node
# are in the refSet
elif (refArr[i].prev in refSet
and refArr[i].next in refSet):
connectedComponents -= 1
# the case when previous and next
# siblings of the current node
# are not in the refSet'''
elif (refArr[i].prev not in refSet
and refArr[i].next not in refSet):
connectedComponents += 1
return connectedComponents;
# Function to add a node at the
# beginging of the Doubly Linked List
def push(head_ref, new_data):
''' allocate node '''
new_node = Node()
current_node = new_node;
''' put in the data '''
new_node.data = new_data;
''' since we are adding at the beginning,
prev is always None '''
new_node.prev = None;
''' link the old list off the new node '''
new_node.next = (head_ref);
''' change prev of head node to new node '''
if ((head_ref) != None):
(head_ref).prev = new_node;
''' move the head to point to the new node '''
(head_ref) = new_node;
return current_node, head_ref;
# Function to print nodes in a given
# doubly linked list
def printList(node):
while (node != None):
print(node.data, end = ' ');
node = node.next;
# Driver code
if __name__=='__main__':
# Start with the empty list
head = None;
# Let us create a linked list to test
# the functions so as to find number
# of Connected Components Created a
# doubly linked list: 1 <. 7 <. 10 <. 5 <. 4 <. 2
ref_to_nodeN2, head = push(head, 2);
ref_to_nodeN4, head = push(head, 4)
ref_to_nodeN5, head = push(head, 5)
ref_to_nodeN10, head = push(head, 10)
ref_to_nodeN7, head = push(head, 7)
ref_to_nodeN1, head = push(head, 1)
refArr = [ref_to_nodeN5, ref_to_nodeN2, ref_to_nodeN7, ref_to_nodeN1]
# This function will return the number
# of connected components of doubly linked list
connectedComponents = func_connComp(head, refArr, 4);
print("Total number of connected components are ", connectedComponents)
# This code is contributed by rutvik_56
Total number of connected components are 3
时间复杂度: O(m)
空间复杂度: O(m)其中,m =参考数组’refArr’的大小
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。