删除链表中重复的节点:
首先删除链表的节点我们必然需要至少两个指针,跑在前面的叫head,后面的叫post。首先把遍历整个链表的代码(不加删除节点)写出来:
private HashSet<Integer> set = new HashSet<>(); public ListNode deleteDuplication(ListNode pHead) { ListNode head = pHead; ListNode post = pHead; while(head != null){ set.add(head.val); head = head.next; post.next = head; post = post.next; } return pHead; }
然后遇到重复的节点只需要head = head.next
,删除节点时只需要 post.next = head
即可。所以代码的雏形就出来了:(注意,这里只是去掉多余的重复节点即1->2->3->4->5,而题中要求去掉所有重复节点1->2->5)。
private HashSet<Integer> set = new HashSet<>(); public ListNode deleteDuplication(ListNode pHead) { ListNode head = pHead; ListNode post = pHead; while(head != null){ set.add(head.val); head = head.next; while(head != null && set.contains(head.val)){ head = head.next; } post.next = head; post = post.next; } return pHead; }
所以我们需要两个set用来找到重复的节点结合。代码如下:
private HashSet<Integer> setAll = new HashSet<>(); private HashSet<Integer> set = new HashSet<>(); while(head != null){ if(setAll.contains(head.val)) set.add(head.val); setAll.add(head.val); head = head.next; }
剩余的代码和前面一样,只不过由于第一个节点也有可能是重复节点,所以需要多一次过滤,从第一个不是重复的节点开始。完整的代码如下:
private HashSet<Integer> setAll = new HashSet<>(); private HashSet<Integer> set = new HashSet<>(); public ListNode deleteDuplication(ListNode pHead) { ListNode head = pHead; ListNode post = pHead; while(head != null){ if(setAll.contains(head.val)) set.add(head.val); setAll.add(head.val); head = head.next; } head = pHead; while(head != null && set.contains(head.val)){ head = head.next; } pHead = head; post = pHead; while(head != null){ head = head.next; while(head != null && set.contains(head.val)){ head = head.next; } post.next = head; post = post.next; } return pHead; }