📌  相关文章
📜  从未排序的双向链表中删除重复项(1)

📅  最后修改于: 2023-12-03 15:22:00.303000             🧑  作者: Mango

从未排序的双向链表中删除重复项

当我们有一个没有排序的双向链表,需要删除其中的重复项时,我们可以采用以下步骤:

  1. 定义一个 HashMap 或 HashSet 来存储链表中出现过的元素。
  2. 遍历整个链表,对于每个节点,检查其数据是否已经在 HashMap 或 HashSet 中出现过。
  3. 如果数据已经出现过,则将该节点从链表中删除;如果数据未出现过,则将该数据添加进 HashMap 或 HashSet 中记录。
  4. 最后,返回更新后的链表。

下面是具体实现的伪代码:

// 首先,定义一个双向链表节点的类

class ListNode {
    int val;
    ListNode prev, next;
    ListNode(int x) {
        val = x;
    }
}

// 接下来,定义一个函数来删除重复项

ListNode removeDuplicates(ListNode head) {
    if (head == null) { // 如果链表为空,则直接返回空
        return null;
    }

    // 定义一个 HashMap 或 HashSet 来存储已经出现的节点数据
    Set<Integer> set = new HashSet<>();

    ListNode p = head;

    while (p != null) { // 遍历整个链表
        if (set.contains(p.val)) { // 如果数据已经出现过
            // 将该节点从链表中删除
            p.prev.next = p.next;
            if (p.next != null) {
                p.next.prev = p.prev;
            }
        } else { // 如果数据未出现过
            // 将该数据添加进 set 中记录
            set.add(p.val);
        }
        p = p.next; // 继续遍历下一个节点
    }
    return head; // 返回更新后的链表
}

上述代码中,我们利用了 HashSet 来存储链表中出现过的元素,并通过遍历链表的方式删除重复项、返回更新后的链表。这种方法的时间复杂度为 $O(N)$,其中 $N$ 为链表长度,空间复杂度也为 $O(N)$。

除了使用 HashSet 以外,我们也可以使用 HashMap,将节点数据作为键、节点本身作为值存储在 Map 中,来记录已经出现的节点。这种方法也可以实现链表中删除重复项的功能,但需要额外的空间来存储节点信息,因此空间复杂度比 HashSet 高一些。