两个链表的并集和交集的Java程序
给定两个链表,创建并集和交集列表,其中包含给定列表中元素的并集和交集。输出列表中元素的顺序无关紧要。
例子:
Input:
List1: 10->15->4->20
List2: 8->4->2->10
Output:
Intersection List: 4->10
Union List: 2->8->20->4->15->10
方法1(简单):
以下是分别获取并集和交集列表的简单算法。
1、路口(list1,list2):
将结果列表初始化为 NULL。遍历list1并查找list2中的每个元素,如果该元素存在于list2中,则将该元素添加到结果中。
2.联合(list1,list2):
将结果列表初始化为 NULL。遍历 list1 并将其所有元素添加到结果中。
遍历list2。如果 list2 的元素已经存在于结果中,则不要将其插入结果中,否则插入。
此方法假定给定列表中没有重复项。
感谢 Shekhu 提出这种方法。以下是此方法的 C 和Java实现。
Java
// Java program to find union and
// intersection of two unsorted
// linked lists
class LinkedList
{
// head of list
Node head;
// Linked list Node
class Node
{
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
/* Function to get Union of 2
Linked Lists */
void getUnion(Node head1,
Node head2)
{
Node t1 = head1, t2 = head2;
// Insert all elements of list1
// in the result
while (t1 != null)
{
push(t1.data);
t1 = t1.next;
}
// Insert those elements of list2
// that are not present
while (t2 != null)
{
if (!isPresent(head, t2.data))
push(t2.data);
t2 = t2.next;
}
}
void getIntersection(Node head1,
Node head2)
{
Node result = null;
Node t1 = head1;
// Traverse list1 and search each
// element of it in list2.
// If the element is present in
// list 2, then insert the
// element to result
while (t1 != null)
{
if (isPresent(head2, t1.data))
push(t1.data);
t1 = t1.next;
}
}
// Utility function to print list
void printList()
{
Node temp = head;
while (temp != null)
{
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
/* Inserts a node at start of
linked list */
void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to
new Node */
head = new_node;
}
/* A utility function that returns true
if data is present in linked list
else return false */
boolean isPresent(Node head, int data)
{
Node t = head;
while (t != null) {
if (t.data == data)
return true;
t = t.next;
}
return false;
}
// Driver code
public static void main(String args[])
{
LinkedList llist1 = new LinkedList();
LinkedList llist2 = new LinkedList();
LinkedList unin = new LinkedList();
LinkedList intersection = new LinkedList();
/* Create a linked lists 10->15->5->20 */
llist1.push(20);
llist1.push(4);
llist1.push(15);
llist1.push(10);
/* Create a linked lists 8->4->2->10 */
llist2.push(10);
llist2.push(2);
llist2.push(4);
llist2.push(8);
intersection.getIntersection(llist1.head,
llist2.head);
unin.getUnion(llist1.head, llist2.head);
System.out.println("First List is");
llist1.printList();
System.out.println("Second List is");
llist2.printList();
System.out.println("Intersection List is");
intersection.printList();
System.out.println("Union List is");
unin.printList();
}
}
// This code is contributed by Rajat Mishra
Java
// Java code for Union and Intersection
// of two Linked Lists
import java.util.HashMap;
import java.util.HashSet;
class LinkedList
{
// head of list
Node head;
// Linked list Node
class Node
{
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
// Utility function to print list
void printList()
{
Node temp = head;
while (temp != null)
{
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
/* Inserts a node at start of
linked list */
void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to
new Node */
head = new_node;
}
public void append(int new_data)
{
if (this.head == null)
{
Node n = new Node(new_data);
this.head = n;
return;
}
Node n1 = this.head;
Node n2 = new Node(new_data);
while (n1.next != null)
{
n1 = n1.next;
}
n1.next = n2;
n2.next = null;
}
/* A utility function that returns true
if data is present in linked list else
return false */
boolean isPresent(Node head, int data)
{
Node t = head;
while (t != null)
{
if (t.data == data)
return true;
t = t.next;
}
return false;
}
LinkedList getIntersection(Node head1,
Node head2)
{
HashSet hset = new HashSet<>();
Node n1 = head1;
Node n2 = head2;
LinkedList result = new LinkedList();
// Loop stores all the elements of
// list1 in hset
while (n1 != null)
{
if (hset.contains(n1.data))
{
hset.add(n1.data);
}
else
{
hset.add(n1.data);
}
n1 = n1.next;
}
// For every element of list2 present
// in hset loop inserts the element
// into the result
while (n2 != null)
{
if (hset.contains(n2.data))
{
result.push(n2.data);
}
n2 = n2.next;
}
return result;
}
LinkedList getUnion(Node head1,
Node head2)
{
// HashMap that will store the
// elements of the lists with their counts
HashMap hmap =
new HashMap<>();
Node n1 = head1;
Node n2 = head2;
LinkedList result = new LinkedList();
// Loop inserts the elements and the
// count of that element of list1 into
// the hmap
while (n1 != null)
{
if (hmap.containsKey(n1.data))
{
int val = hmap.get(n1.data);
hmap.put(n1.data, val + 1);
}
else
{
hmap.put(n1.data, 1);
}
n1 = n1.next;
}
// Loop further adds the elements of
// list2 with their counts into the hmap
while (n2 != null)
{
if (hmap.containsKey(n2.data))
{
int val = hmap.get(n2.data);
hmap.put(n2.data, val + 1);
}
else
{
hmap.put(n2.data, 1);
}
n2 = n2.next;
}
// Eventually add all the elements
// into the result that are present in the hmap
for (int a : hmap.keySet()) {
result.append(a);
}
return result;
}
// Driver code
public static void main(String args[])
{
LinkedList llist1 = new LinkedList();
LinkedList llist2 = new LinkedList();
LinkedList union = new LinkedList();
LinkedList intersection = new LinkedList();
/*create a linked list 10->15->4->20 */
llist1.push(20);
llist1.push(4);
llist1.push(15);
llist1.push(10);
/*create a linked list 8->4->2->10 */
llist2.push(10);
llist2.push(2);
llist2.push(4);
llist2.push(8);
intersection =
intersection.getIntersection(llist1.head,
llist2.head);
union = union.getUnion(llist1.head,
llist2.head);
System.out.println("First List is");
llist1.printList();
System.out.println("Second List is");
llist2.printList();
System.out.println("Intersection List is");
intersection.printList();
System.out.println("Union List is");
union.printList();
}
}
// This code is contributed by Kamal Rawal
输出:
First list is
10 15 4 20
Second list is
8 4 2 10
Intersection list is
4 10
Union list is
2 8 20 4 15 10
复杂性分析:
- 时间复杂度: O(m*n)。
这里的“m”和“n”分别是第一个和第二个列表中存在的元素数。
对于联合:对于 list-2 中的每个元素,我们检查该元素是否已经存在于使用 list-1 生成的结果列表中。
对于交集:对于 list-1 中的每个元素,我们检查该元素是否也存在于 list-2 中。 - 辅助空间: O(1)。
不使用任何数据结构来存储值。
方法二(使用归并排序):
在这种方法中,Union 和 Intersection 的算法非常相似。首先,我们对给定的列表进行排序,然后遍历排序的列表以获得并集和交集。
以下是获取联合和交集列表的步骤。
- 使用归并排序对第一个链表进行排序。这一步需要 O(mLogm) 时间。有关此步骤的详细信息,请参阅此帖子。
- 使用归并排序对第二个链表进行排序。这一步需要 O(nLogn) 时间。有关此步骤的详细信息,请参阅此帖子。
- 线性扫描两个排序列表以获得并集和交集。这一步需要 O(m + n) 时间。此步骤可以使用与此处讨论的排序数组算法相同的算法来实现。
该方法的时间复杂度为 O(mLogm + nLogn),优于方法 1 的时间复杂度。
方法3(使用散列):
1.联合(list1,list2):
将结果列表初始化为 NULL 并创建一个空的哈希表。一个一个地遍历两个列表,对于每个被访问的元素,查看哈希表中的元素。如果该元素不存在,则将该元素插入到结果列表中。如果元素存在,则忽略它。
2. 路口(list1,list2)
将结果列表初始化为 NULL 并创建一个空的哈希表。遍历列表1。对于 list1 中访问的每个元素,将元素插入哈希表中。遍历list2,对于list2中被访问的每一个元素,查找哈希表中的元素。如果该元素存在,则将该元素插入到结果列表中。如果该元素不存在,则忽略它。
上述两种方法都假设没有重复。
Java
// Java code for Union and Intersection
// of two Linked Lists
import java.util.HashMap;
import java.util.HashSet;
class LinkedList
{
// head of list
Node head;
// Linked list Node
class Node
{
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
// Utility function to print list
void printList()
{
Node temp = head;
while (temp != null)
{
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
/* Inserts a node at start of
linked list */
void push(int new_data)
{
/* 1 & 2: Allocate the Node &
Put in the data*/
Node new_node = new Node(new_data);
/* 3. Make next of new Node as head */
new_node.next = head;
/* 4. Move the head to point to
new Node */
head = new_node;
}
public void append(int new_data)
{
if (this.head == null)
{
Node n = new Node(new_data);
this.head = n;
return;
}
Node n1 = this.head;
Node n2 = new Node(new_data);
while (n1.next != null)
{
n1 = n1.next;
}
n1.next = n2;
n2.next = null;
}
/* A utility function that returns true
if data is present in linked list else
return false */
boolean isPresent(Node head, int data)
{
Node t = head;
while (t != null)
{
if (t.data == data)
return true;
t = t.next;
}
return false;
}
LinkedList getIntersection(Node head1,
Node head2)
{
HashSet hset = new HashSet<>();
Node n1 = head1;
Node n2 = head2;
LinkedList result = new LinkedList();
// Loop stores all the elements of
// list1 in hset
while (n1 != null)
{
if (hset.contains(n1.data))
{
hset.add(n1.data);
}
else
{
hset.add(n1.data);
}
n1 = n1.next;
}
// For every element of list2 present
// in hset loop inserts the element
// into the result
while (n2 != null)
{
if (hset.contains(n2.data))
{
result.push(n2.data);
}
n2 = n2.next;
}
return result;
}
LinkedList getUnion(Node head1,
Node head2)
{
// HashMap that will store the
// elements of the lists with their counts
HashMap hmap =
new HashMap<>();
Node n1 = head1;
Node n2 = head2;
LinkedList result = new LinkedList();
// Loop inserts the elements and the
// count of that element of list1 into
// the hmap
while (n1 != null)
{
if (hmap.containsKey(n1.data))
{
int val = hmap.get(n1.data);
hmap.put(n1.data, val + 1);
}
else
{
hmap.put(n1.data, 1);
}
n1 = n1.next;
}
// Loop further adds the elements of
// list2 with their counts into the hmap
while (n2 != null)
{
if (hmap.containsKey(n2.data))
{
int val = hmap.get(n2.data);
hmap.put(n2.data, val + 1);
}
else
{
hmap.put(n2.data, 1);
}
n2 = n2.next;
}
// Eventually add all the elements
// into the result that are present in the hmap
for (int a : hmap.keySet()) {
result.append(a);
}
return result;
}
// Driver code
public static void main(String args[])
{
LinkedList llist1 = new LinkedList();
LinkedList llist2 = new LinkedList();
LinkedList union = new LinkedList();
LinkedList intersection = new LinkedList();
/*create a linked list 10->15->4->20 */
llist1.push(20);
llist1.push(4);
llist1.push(15);
llist1.push(10);
/*create a linked list 8->4->2->10 */
llist2.push(10);
llist2.push(2);
llist2.push(4);
llist2.push(8);
intersection =
intersection.getIntersection(llist1.head,
llist2.head);
union = union.getUnion(llist1.head,
llist2.head);
System.out.println("First List is");
llist1.printList();
System.out.println("Second List is");
llist2.printList();
System.out.println("Intersection List is");
intersection.printList();
System.out.println("Union List is");
union.printList();
}
}
// This code is contributed by Kamal Rawal
输出:
First List is
10 15 4 20
Second List is
8 4 2 10
Intersection List is
10 4
Union List is
2 4 20 8 10 15
复杂性分析:
- 时间复杂度: O(m+n)。
这里的“m”和“n”分别是第一个和第二个列表中存在的元素数。
对于联合:遍历两个列表,将元素存储在 Hash-map 中并更新各自的计数。
对于交集:首先遍历 list-1,将其元素存储在 Hash-map 中,然后对 list-2 中的每个元素检查它是否已经存在于 map 中。这需要 O(1) 时间。 - 辅助空间: O(m+n)。
使用 Hash-map 数据结构来存储值。
请参阅关于两个链表的并集和交集的完整文章以获取更多详细信息!