import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * public ListNode(int val) { * this.val = val; * } * } */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param head ListNode类 * @return ListNode类 */ public ListNode deleteDuplicates (ListNode head) { // write code here // 借助容器,要求该容器:能统计次数(HashMap) // 算法的时间复杂度O(N),额外空间复杂度O(N) // 1.处理特殊链表 if (head == null || head.next == null) { // 对于空链表,单结点链表,直接返回head return head; } // 2.遍历链表,统计结点的值与对应的出现次数 HashMap<Integer, Integer> countMap = new HashMap<>(); ListNode cur = head; while (cur != null) { if (!countMap.containsKey(cur.val)) { // 如果HashMap中没有这个key,说明是第一次出现 countMap.put(cur.val, 1); } else { // 如果HashMap中有这个key,说明是并非第一次出现 int count = countMap.get(cur.val); count++; countMap.put(cur.val, count); } cur = cur.next; } // 3.再次遍历链表,找出其值只出现过1次的结点,将其连接起来 // 3.1 先把head定位到链表中第一个其值只出现了一次的结点 cur = head; head = null; while (cur != null) { if (countMap.get(cur.val) == 1) { // 当前结点的值只出现了一次 head = cur; break; } cur = cur.next; } if (head == null) { // 如果遍历了一轮链表,发现head还是null,说明整个链表全是值重复结点 return null; } // 3.2 此时,head和cur指向了第一个不重复结点,继续遍历链表,使用尾插法持续纳入不重复结点 ListNode tail = head; cur = cur.next; while (cur != null) { if (countMap.get(cur.val) == 1) { // 当前结点只出现了一次 tail.next = cur; tail = cur; } cur = cur.next; } // 3.3 给最后一个结点的next指向null,防止带出来值重复的结点 tail.next = null; // 4.返回头部 return head; } }