给定两个以递增顺序排序的列表,请创建并返回一个新列表,该列表代表两个列表的交集。新列表应使用自己的内存制作-原始列表不应更改。
例子:
Input:
First linked list: 1->2->3->4->6
Second linked list be 2->4->6->8,
Output: 2->4->6.
The elements 2, 4, 6 are common in
both the list so they appear in the
intersection list.
Input:
First linked list: 1->2->3->4->5
Second linked list be 2->3->4,
Output: 2->3->4
The elements 2, 3, 4 are common in
both the list so they appear in the
intersection list.
方法1 :使用虚拟节点。
方法:
这个想法是在结果列表的开始使用一个临时的虚拟节点。指针尾部始终指向结果列表中的最后一个节点,因此可以轻松添加新节点。虚拟节点最初为尾部提供指向的存储空间。该虚拟节点是有效的,因为它只是临时的,并且在堆栈中分配。循环继续进行,从“ a”或“ b”中删除一个节点并将其添加到尾部。当遍历给定列表时,结果在dummy.next中,因为值是从哑元的下一个节点分配的。如果两个元素相等,则将其都移除,然后将元素插入尾部。否则,删除两个列表中较小的元素。
下面是上述方法的实现:
C++
#include
using namespace std;
/* Link list node */
struct Node {
int data;
Node* next;
};
void push(Node** head_ref, int new_data);
/*This solution uses the temporary
dummy to build up the result list */
Node* sortedIntersect(Node* a, Node* b)
{
Node dummy;
Node* tail = &dummy;
dummy.next = NULL;
/* Once one or the other
list runs out -- we're done */
while (a != NULL && b != NULL) {
if (a->data == b->data) {
push((&tail->next), a->data);
tail = tail->next;
a = a->next;
b = b->next;
}
/* advance the smaller list */
else if (a->data < b->data)
a = a->next;
else
b = b->next;
}
return (dummy.next);
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at
the beginning of the linked list */
void push(Node** head_ref, int new_data)
{
/* allocate node */
Node* new_node = (Node*)malloc(
sizeof(Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in
a given linked list */
void printList(Node* node)
{
while (node != NULL) {
cout << node->data <<" ";
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty lists */
Node* a = NULL;
Node* b = NULL;
Node* intersect = NULL;
/* Let us create the first sorted
linked list to test the functions
Created linked list will be
1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
cout<<"Linked list containing common items of a & b \n";
printList(intersect);
}
C
#include
#include
/* Link list node */
struct Node {
int data;
struct Node* next;
};
void push(struct Node** head_ref, int new_data);
/*This solution uses the temporary
dummy to build up the result list */
struct Node* sortedIntersect(
struct Node* a,
struct Node* b)
{
struct Node dummy;
struct Node* tail = &dummy;
dummy.next = NULL;
/* Once one or the other
list runs out -- we're done */
while (a != NULL && b != NULL) {
if (a->data == b->data) {
push((&tail->next), a->data);
tail = tail->next;
a = a->next;
b = b->next;
}
/* advance the smaller list */
else if (a->data < b->data)
a = a->next;
else
b = b->next;
}
return (dummy.next);
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at
the beginning of the linked list */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*)malloc(
sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in
a given linked list */
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty lists */
struct Node* a = NULL;
struct Node* b = NULL;
struct Node* intersect = NULL;
/* Let us create the first sorted
linked list to test the functions
Created linked list will be
1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
printf("\n Linked list containing common items of a & b \n ");
printList(intersect);
getchar();
}
Java
class GFG
{
// head nodes for pointing to 1st and 2nd linked lists
static Node a = null, b = null;
// dummy node for storing intersection
static Node dummy = null;
// tail node for keeping track of
// last node so that it makes easy for insertion
static Node tail = null;
// class - Node
static class Node {
int data;
Node next;
Node(int data) {
this.data = data;
next = null;
}
}
// function for printing the list
void printList(Node start) {
Node p = start;
while (p != null) {
System.out.print(p.data + " ");
p = p.next;
}
System.out.println();
}
// inserting elements into list
void push(int data) {
Node temp = new Node(data);
if(dummy == null) {
dummy = temp;
tail = temp;
}
else {
tail.next = temp;
tail = temp;
}
}
// function for finding intersection and adding it to dummy list
void sortedIntersect()
{
// pointers for iterating
Node p = a,q = b;
while(p != null && q != null)
{
if(p.data == q.data)
{
// add to dummy list
push(p.data);
p = p.next;
q = q.next;
}
else if(p.data < q.data)
p = p.next;
else
q= q.next;
}
}
// Driver code
public static void main(String args[])
{
GFG list = new GFG();
// creating first linked list
list.a = new Node(1);
list.a.next = new Node(2);
list.a.next.next = new Node(3);
list.a.next.next.next = new Node(4);
list.a.next.next.next.next = new Node(6);
// creating second linked list
list.b = new Node(2);
list.b.next = new Node(4);
list.b.next.next = new Node(6);
list.b.next.next.next = new Node(8);
// function call for intersection
list.sortedIntersect();
// print required intersection
System.out.println("Linked list containing common items of a & b");
list.printList(dummy);
}
}
// This code is contributed by Likhita AVL
Python3
''' Link list node '''
class Node:
def __init__(self):
self.data = 0
self.next = None
'''This solution uses the temporary
dummy to build up the result list '''
def sortedIntersect(a, b):
dummy = Node()
tail = dummy;
dummy.next = None;
''' Once one or the other
list runs out -- we're done '''
while (a != None and b != None):
if (a.data == b.data):
tail.next = push((tail.next), a.data);
tail = tail.next;
a = a.next;
b = b.next;
# advance the smaller list
elif(a.data < b.data):
a = a.next;
else:
b = b.next;
return (dummy.next);
''' UTILITY FUNCTIONS '''
''' Function to insert a node at
the beginning of the linked list '''
def push(head_ref, new_data):
''' allocate node '''
new_node = Node()
''' put in the data '''
new_node.data = new_data;
''' link the old list off the new node '''
new_node.next = (head_ref);
''' move the head to point to the new node '''
(head_ref) = new_node;
return head_ref
''' Function to print nodes in
a given linked list '''
def printList(node):
while (node != None):
print(node.data, end=' ')
node = node.next;
''' Driver code'''
if __name__=='__main__':
''' Start with the empty lists '''
a = None;
b = None;
intersect = None;
''' Let us create the first sorted
linked list to test the functions
Created linked list will be
1.2.3.4.5.6 '''
a = push(a, 6);
a = push(a, 5);
a = push(a, 4);
a = push(a, 3);
a = push(a, 2);
a = push(a, 1);
''' Let us create the second sorted linked list
Created linked list will be 2.4.6.8 '''
b = push(b, 8);
b = push(b, 6);
b = push(b, 4);
b = push(b, 2);
''' Find the intersection two linked lists '''
intersect = sortedIntersect(a, b);
print("Linked list containing common items of a & b ");
printList(intersect);
# This code is contributed by rutvik_56.
C
#include
#include
/* Link list node */
struct Node {
int data;
struct Node* next;
};
void push(struct Node** head_ref,
int new_data);
/* This solution uses the local reference */
struct Node* sortedIntersect(
struct Node* a,
struct Node* b)
{
struct Node* result = NULL;
struct Node** lastPtrRef = &result;
/* Advance comparing the first
nodes in both lists.
When one or the other list runs
out, we're done. */
while (a != NULL && b != NULL) {
if (a->data == b->data) {
/* found a node for the intersection */
push(lastPtrRef, a->data);
lastPtrRef = &((*lastPtrRef)->next);
a = a->next;
b = b->next;
}
else if (a->data < b->data)
a = a->next; /* advance the smaller list */
else
b = b->next;
}
return (result);
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at the
beginging of the linked list */
void push(struct Node** head_ref,
int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*)malloc(
sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty lists */
struct Node* a = NULL;
struct Node* b = NULL;
struct Node* intersect = NULL;
/* Let us create the first sorted
linked list to test the functions
Created linked list will be
1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
printf("\n Linked list containing common items of a & b \n ");
printList(intersect);
getchar();
}
C
#include
#include
/* Link list node */
struct Node {
int data;
struct Node* next;
};
struct Node* sortedIntersect(
struct Node* a,
struct Node* b)
{
/* base case */
if (a == NULL || b == NULL)
return NULL;
/* If both lists are non-empty */
/* advance the smaller list and call recursively */
if (a->data < b->data)
return sortedIntersect(a->next, b);
if (a->data > b->data)
return sortedIntersect(a, b->next);
// Below lines are executed only
// when a->data == b->data
struct Node* temp
= (struct Node*)malloc(
sizeof(struct Node));
temp->data = a->data;
/* advance both lists and call recursively */
temp->next = sortedIntersect(a->next, b->next);
return temp;
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at
the beginging of the linked list */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node
= (struct Node*)malloc(
sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty lists */
struct Node* a = NULL;
struct Node* b = NULL;
struct Node* intersect = NULL;
/* Let us create the first sorted
linked list to test the functions
Created linked list will be
1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
printf("\n Linked list containing common items of a & b \n ");
printList(intersect);
return 0;
}
输出:
Linked list containing common items of a & b
2 4 6
复杂度分析:
- 时间复杂度: O(m + n),其中m和n分别是第一链表和第二链表中的节点数。
仅需要遍历列表之一。 - 辅助空间: O(min(m,n))。
输出列表最多可以存储min(m,n)个节点。
方法2 :使用本地引用。
方法:此解决方案在结构上与上述解决方案非常相似,但避免使用虚拟节点,而是维护一个结构节点**指针lastPtrRef,该指针始终指向结果列表的最后一个指针。这解决了虚拟节点所做的相同情况—在结果列表为空时处理结果列表。如果列表建立在其尾部,则可以使用虚拟节点或结构节点**“引用”策略。
下面是上述方法的实现:
C
#include
#include
/* Link list node */
struct Node {
int data;
struct Node* next;
};
void push(struct Node** head_ref,
int new_data);
/* This solution uses the local reference */
struct Node* sortedIntersect(
struct Node* a,
struct Node* b)
{
struct Node* result = NULL;
struct Node** lastPtrRef = &result;
/* Advance comparing the first
nodes in both lists.
When one or the other list runs
out, we're done. */
while (a != NULL && b != NULL) {
if (a->data == b->data) {
/* found a node for the intersection */
push(lastPtrRef, a->data);
lastPtrRef = &((*lastPtrRef)->next);
a = a->next;
b = b->next;
}
else if (a->data < b->data)
a = a->next; /* advance the smaller list */
else
b = b->next;
}
return (result);
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at the
beginging of the linked list */
void push(struct Node** head_ref,
int new_data)
{
/* allocate node */
struct Node* new_node = (struct Node*)malloc(
sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty lists */
struct Node* a = NULL;
struct Node* b = NULL;
struct Node* intersect = NULL;
/* Let us create the first sorted
linked list to test the functions
Created linked list will be
1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
printf("\n Linked list containing common items of a & b \n ");
printList(intersect);
getchar();
}
输出:
Linked list containing common items of a & b
2 4 6
复杂度分析:
- 时间复杂度: O(m + n),其中m和n分别是第一链表和第二链表中的节点数。
仅需要遍历列表之一。 - 辅助空间: O(max(m,n))。
输出列表最多可以存储m + n个节点。
方法3 :递归解决方案。
方法:
递归方法与以上两种方法非常相似。构建一个包含两个节点并返回链接列表节点的递归函数。比较两个列表的第一个元素。
- 如果它们相似,则用两个列表的下一个节点调用递归函数。使用当前节点的数据创建一个节点,并将从递归函数返回的节点放入所创建节点的下一个指针。返回创建的节点。
- 如果值不相等,则删除两个列表中的较小节点,然后调用递归函数。
下面是上述方法的实现:
C
#include
#include
/* Link list node */
struct Node {
int data;
struct Node* next;
};
struct Node* sortedIntersect(
struct Node* a,
struct Node* b)
{
/* base case */
if (a == NULL || b == NULL)
return NULL;
/* If both lists are non-empty */
/* advance the smaller list and call recursively */
if (a->data < b->data)
return sortedIntersect(a->next, b);
if (a->data > b->data)
return sortedIntersect(a, b->next);
// Below lines are executed only
// when a->data == b->data
struct Node* temp
= (struct Node*)malloc(
sizeof(struct Node));
temp->data = a->data;
/* advance both lists and call recursively */
temp->next = sortedIntersect(a->next, b->next);
return temp;
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at
the beginging of the linked list */
void push(struct Node** head_ref, int new_data)
{
/* allocate node */
struct Node* new_node
= (struct Node*)malloc(
sizeof(struct Node));
/* put in the data */
new_node->data = new_data;
/* link the old list off the new node */
new_node->next = (*head_ref);
/* move the head to point to the new node */
(*head_ref) = new_node;
}
/* Function to print nodes in a given linked list */
void printList(struct Node* node)
{
while (node != NULL) {
printf("%d ", node->data);
node = node->next;
}
}
/* Driver program to test above functions*/
int main()
{
/* Start with the empty lists */
struct Node* a = NULL;
struct Node* b = NULL;
struct Node* intersect = NULL;
/* Let us create the first sorted
linked list to test the functions
Created linked list will be
1->2->3->4->5->6 */
push(&a, 6);
push(&a, 5);
push(&a, 4);
push(&a, 3);
push(&a, 2);
push(&a, 1);
/* Let us create the second sorted linked list
Created linked list will be 2->4->6->8 */
push(&b, 8);
push(&b, 6);
push(&b, 4);
push(&b, 2);
/* Find the intersection two linked lists */
intersect = sortedIntersect(a, b);
printf("\n Linked list containing common items of a & b \n ");
printList(intersect);
return 0;
}
输出:
Linked list containing common items of a & b
2 4 6
复杂度分析:
- 时间复杂度: O(m + n),其中m和n分别是第一链表和第二链表中的节点数。
仅需要遍历列表之一。 - 辅助空间: O(max(m,n))。
输出列表最多可以存储m + n个节点。