修改链表以包含每个重复元素的最后一次出现
给定一个由N个可能包含重复元素的节点组成的未排序单链表,任务是从链表中删除除最后一次出现的重复元素之外的所有元素。
例子:
Input: 1 -> 2 -> 7 -> 3 -> 2 -> 5 -> 1
Output: 7 -> 3 -> 2 -> 5 -> 1
Explanation:
Given Linked List: 1 -> 2 -> 7 -> 3 -> 2 -> 5 -> 1
Duplicate elements: 1, 2
Modified Linked List: 7 -> 3 -> 2 -> 5 -> 1
Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 2 -> 3 -> 4 -> 5
处理方法:按照以下步骤解决问题:
- 初始化一个虚拟节点并使其成为head的下一个点。
- 反转给定的链表。
- 初始化一个无序集,比如访问过的,来存储已经访问过的节点。
- 初始化两个节点,比如currnode,指向虚拟节点, nextnode,存储当前节点的下一个节点。
- 遍历链表并检查当前节点的下一个节点的数据是否已经被访问过。
- 如果已经访问过,则执行以下步骤:
- 初始化一个新节点,例如duplicate ,以存储在这种情况下是重复节点的nextnode 。
- 使当前的下一个点到下一个的nextnode的。
- 除此以外:
- 将nextnode的数据插入到访问集中。
- 将nextnode设为currentnode 。
- 最后,反转修改后的链表并返回。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Node class
class Node {
public:
int data;
Node* next;
Node(int x)
{
this->data = x;
this->next = NULL;
}
};
// Function to reverse a Linked List
Node* reverseList(Node* head)
{
Node *prev = NULL, *nextNode = NULL;
while (head != NULL) {
// Point to next node
// of the current node
nextNode = head->next;
// Point next of current
// to the previous node
head->next = prev;
prev = head;
head = nextNode;
}
return prev;
}
// Function to modify a linked list
// such that it contains only the
// last occurrence of duplicate elements
Node* Remove_Dup_Keep_Last_Occurence(
Node* head)
{
// Make a dummy node
Node* dummy = new Node(-1);
dummy->next = head;
// Reverse the given Linked List
dummy->next = reverseList(dummy->next);
// Stores duplicate elements
unordered_set visited;
Node *currNode = dummy, *nextNode;
// Iterate over the list
while (currNode != NULL
&& currNode->next != NULL) {
nextNode = currNode->next;
// Check if data of the next node of the
// current node is already visited or not
if (visited.count(nextNode->data) != 0) {
// Stores the duplicate pointer
Node* duplicate = nextNode;
currNode->next = nextNode->next;
// Erase memory of duplicate pointer
delete duplicate;
}
else {
// Mark as visited to data of nextNode
visited.insert(nextNode->data);
// Go for the next node
currNode = nextNode;
}
}
// Reverse the modified linked list
dummy->next = reverseList(dummy->next);
return dummy->next;
}
// Function to print a Linked List
void print_Linked_List(Node* head)
{
Node* curr = head;
while (curr != NULL) {
cout << curr->data << ' ';
curr = curr->next;
}
}
// Driver Code
int main()
{
// Given Input
Node* head = new Node(3);
head->next = new Node(2);
head->next->next = new Node(3);
head->next->next->next = new Node(1);
head->next->next->next->next = new Node(5);
head->next->next->next->next->next = new Node(1);
head->next->next->next->next->next->next = new Node(6);
head = Remove_Dup_Keep_Last_Occurence(head);
// Function Call
print_Linked_List(head);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG
{
// Node class
static class Node {
int data;
Node next;
Node(int x)
{
this.data = x;
this.next = null;
}
};
// Function to reverse a Linked List
static Node reverseList(Node head)
{
Node prev = null, nextNode = null;
while (head != null) {
// Point to next node
// of the current node
nextNode = head.next;
// Point next of current
// to the previous node
head.next = prev;
prev = head;
head = nextNode;
}
return prev;
}
// Function to modify a linked list
// such that it contains only the
// last occurrence of duplicate elements
static Node Remove_Dup_Keep_Last_Occurence(
Node head)
{
// Make a dummy node
Node dummy = new Node(-1);
dummy.next = head;
// Reverse the given Linked List
dummy.next = reverseList(dummy.next);
// Stores duplicate elements
HashSet visited = new HashSet();
Node currNode = dummy;
Node nextNode;
// Iterate over the list
while (currNode != null
&& currNode.next != null) {
nextNode = currNode.next;
// Check if data of the next node of the
// current node is already visited or not
if (visited.contains(nextNode.data)) {
// Stores the duplicate pointer
Node duplicate = nextNode;
currNode.next = nextNode.next;
// Erase memory of duplicate pointer
duplicate=null;
}
else {
// Mark as visited to data of nextNode
visited.add(nextNode.data);
// Go for the next node
currNode = nextNode;
}
}
// Reverse the modified linked list
dummy.next = reverseList(dummy.next);
return dummy.next;
}
// Function to print a Linked List
static void print_Linked_List(Node head)
{
Node curr = head;
while (curr != null) {
System.out.print(curr.data +" ");
curr = curr.next;
}
}
// Driver Code
public static void main(String[] args)
{
// Given Input
Node head = new Node(3);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(1);
head.next.next.next.next = new Node(5);
head.next.next.next.next.next = new Node(1);
head.next.next.next.next.next.next = new Node(6);
head = Remove_Dup_Keep_Last_Occurence(head);
// Function Call
print_Linked_List(head);
}
}
// This code is contributed by shikhasingrajput
输出:
2 3 5 1 6
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。