合并两个没有重复的排序链表
合并两个大小为n1和n2 的排序链表。两个链表中的重复项在最终排序的链表中应该只出现一次。
例子:
Input : list1: 1->1->4->5->7
list2: 2->4->7->9
Output : 1 2 4 5 7 9
资料来源:微软关于校园安置和面试问题
方法:以下是步骤:
- 以排序的方式合并两个已排序的链表。参考这篇文章的递归方法。让最终获得的列表为head 。
- 从已排序的链表head 中删除重复项。
C++
// C++ implementation to merge two sorted linked list
// without duplicates
#include
using namespace std;
// structure of a node
struct Node {
int data;
Node* next;
};
// function to get a new node
Node* getNode(int data)
{
// allocate space
Node* temp = (Node*)malloc(sizeof(Node));
// put in data
temp->data = data;
temp->next = NULL;
return temp;
}
// function to merge two sorted linked list
// in a sorted manner
Node* sortedMerge(struct Node* a, struct Node* b)
{
Node* result = NULL;
/* Base cases */
if (a == NULL)
return (b);
else if (b == NULL)
return (a);
/* Pick either a or b, and recur */
if (a->data <= b->data) {
result = a;
result->next = sortedMerge(a->next, b);
}
else {
result = b;
result->next = sortedMerge(a, b->next);
}
return (result);
}
/* The function removes duplicates from a sorted list */
void removeDuplicates(Node* head)
{
/* Pointer to traverse the linked list */
Node* current = head;
/* Pointer to store the next pointer of a node to be deleted*/
Node* next_next;
/* do nothing if the list is empty */
if (current == NULL)
return;
/* Traverse the list till last node */
while (current->next != NULL) {
/* Compare current node with next node */
if (current->data == current->next->data) {
/* The sequence of steps is important*/
next_next = current->next->next;
free(current->next);
current->next = next_next;
}
else /* This is tricky: only advance if no deletion */
{
current = current->next;
}
}
}
// function to merge two sorted linked list
// without duplicates
Node* sortedMergeWithoutDuplicates(Node* head1, Node* head2)
{
// merge two linked list in sorted manner
Node* head = sortedMerge(head1, head2);
// remove duplicates from the list 'head'
removeDuplicates(head);
return head;
}
// function to print the linked list
void printList(Node* head)
{
while (head != NULL) {
cout << head->data << " ";
head = head->next;
}
}
// Driver program to test above
int main()
{
// head1: 1->1->4->5->7
Node* head1 = getNode(1);
head1->next = getNode(1);
head1->next->next = getNode(4);
head1->next->next->next = getNode(5);
head1->next->next->next->next = getNode(7);
// head2: 2->4->7->9
Node* head2 = getNode(2);
head2->next = getNode(4);
head2->next->next = getNode(7);
head2->next->next->next = getNode(9);
Node* head3;
head3 = sortedMergeWithoutDuplicates(head1, head2);
printList(head3);
return 0;
}
Python3
# Python3 implementation to merge two
# sorted linked list without duplicates
# Structure of a node
class Node:
def __init__(self, data):
self.data = data
self.next = None
# Function to get a new node
def getNode(data):
# Allocate space
temp = Node(data)
return temp
# Function to merge two sorted linked
# list in a sorted manner
def sortedMerge(a, b):
result = None
# Base cases
if (a == None):
return(b)
elif (b == None):
return(a)
# Pick either a or b, and recur
if (a.data <= b.data):
result = a
result.next = sortedMerge(a.next, b)
else:
result = b
result.next = sortedMerge(a, b.next)
return(result)
# The function removes duplicates
# from a sorted list
def removeDuplicates(head):
# Pointer to traverse the linked list
current = head
# Pointer to store the next pointer
# of a node to be deleted
next_next = None
# Do nothing if the list is empty
if (current == None):
return
# Traverse the list till last node
while (current.next != None):
# Compare current node with next node
if (current.data == current.next.data):
# The sequence of steps is important
next_next = current.next.next
del (current.next)
current.next = next_next
else:
# This is tricky: only advance
# if no deletion
current = current.next
# Function to merge two sorted linked list
# without duplicates
def sortedMergeWithoutDuplicates(head1, head2):
# Merge two linked list in sorted manner
head = sortedMerge(head1, head2)
# Remove duplicates from the list 'head'
removeDuplicates(head)
return head
# Function to print the linked list
def printList(head):
while (head != None):
print(head.data, end = ' ')
head = head.next
# Driver code
if __name__=='__main__':
# head1: 1.1.4.5.7
head1 = getNode(1)
head1.next = getNode(1)
head1.next.next = getNode(4)
head1.next.next.next = getNode(5)
head1.next.next.next.next = getNode(7)
# head2: 2.4.7.9
head2 = getNode(2)
head2.next = getNode(4)
head2.next.next = getNode(7)
head2.next.next.next = getNode(9)
head3 = sortedMergeWithoutDuplicates(
head1, head2)
printList(head3)
# This code is contributed by rutvik_56
输出:
1 2 4 5 7 9
时间复杂度:O(n1 + n2)。
辅助空间:O(1)。
练习:在两个列表的单次遍历中获得没有重复的最终排序链表。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。