移除重复节点
难度:
标签:
题目描述
Write code to remove duplicates from an unsorted linked list.
Example1:
Input: [1, 2, 3, 3, 2, 1] Output: [1, 2, 3]
Example2:
Input: [1, 1, 1, 1, 2] Output: [1, 2]
Note:
- The length of the list is within the range[0, 20000].
- The values of the list elements are within the range [0, 20000].
Follow Up:
How would you solve this problem if a temporary buffer is not allowed?
代码结果
运行时间: 68 ms, 内存: 20.6 MB
/*
* 思路:
* 1. 将链表转换为流,去除重复的节点。
* 2. 将结果转换回链表。
*/
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public class Solution {
public ListNode removeDuplicateNodes(ListNode head) {
if (head == null) return head;
List<Integer> values = new LinkedList<>();
ListNode current = head;
while (current != null) {
values.add(current.val);
current = current.next;
}
List<Integer> distinctValues = values.stream().distinct().collect(Collectors.toList());
ListNode dummy = new ListNode(0);
ListNode newCurrent = dummy;
for (int value : distinctValues) {
newCurrent.next = new ListNode(value);
newCurrent = newCurrent.next;
}
return dummy.next;
}
}
解释
方法:
该题解采用哈希表来存储已经出现过的节点的值,以此来检测重复的节点。首先判断如果链表为空或者只有一个节点,则直接返回链表头部。使用两个指针,pre 和 cur,分别表示当前节点的前一个节点和当前节点。pre 初始化为头节点,cur 初始化为头节点的下一个节点。遍历链表,并使用集合 s 存储已经访问过的节点值。在遍历过程中,如果 cur 指向的节点的值在集合 s 中,说明该值已存在,需要将其从链表中移除,即通过修改 pre 的 next 指针实现。如果 cur 指向的节点的值不在集合中,则将该值加入集合,并将 pre 指针移动到 cur。这个过程一直持续到链表末尾。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在实现中使用哈希表来存储节点值的主要优势是什么?为什么不选择其他数据结构如数组或链表?
▷🦆
题解中提到如果链表元素在集合中,则将其移除,但具体如何处理节点的移除?例如,如果`pre.next`已经是`None`,这种情况下如何操作?
▷🦆
为什么在发现节点值重复时,只修改`pre.next`而不需要额外处理`cur`指针?
▷🦆
在题解的代码实现中,当链表只有一个元素时直接返回头结点,这种处理方式是否适用于所有可能的输入情况?
▷