📜  修改链表以包含每个重复元素的最后一次出现

📅  最后修改于: 2022-05-13 01:57:45.969000             🧑  作者: Mango

修改链表以包含每个重复元素的最后一次出现

给定一个由N个可能包含重复元素的节点组成的未排序单链表,任务是从链表中删除除最后一次出现的重复元素之外的所有元素。

例子:

处理方法:按照以下步骤解决问题:



  • 初始化一个虚拟节点并使其成为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 现场工作专业课程学生竞争性编程现场课程