存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3]
输出:[2,3]
提示:
链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序排列来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
//假设使用额外的空间O(n),使用map记录每个节点的val出现的次数,达到一个统计的目的
public ListNode deleteDuplicates(ListNode head) { //使用map key = 具体值,value = 出现的次数 Map<Integer,Integer> map = new HashMap<>(); ListNode current = head; while(current != null){ map.put(current.val,map.getOrDefault(current.val,0)+1); current = current.next; } ListNode result = new ListNode(); current = result; for(Map.Entry<Integer,Integer> entry : map.entrySet()){ if(entry.getValue() == 1){ ListNode temp= new ListNode(entry.getKey()); current.next = temp; current = current.next; } } return result.next; }
结果测试用例是跑不通的了,原因很明显:最后使用map遍历,打乱了链表之前的顺序
//那么就不再使用map遍历了,而是使用链表遍历
public ListNode deleteDuplicates(ListNode head) { //使用map key = 具体值,value = 出现的次数 Map<Integer,Integer> map = new HashMap<>(); ListNode current = head; while(current != null){ map.put(current.val,map.getOrDefault(current.val,0)+1); current = current.next; } ListNode result = new ListNode(0); current = result; while(head != null){ if(map.get(head.val) == 1){ current.next = new ListNode(head.val); current = current.next; } head = head.next; } return result.next; }
这个当然测试用例是ok的,不过同样也存在问题,题目中明显的告诉我们是有序链表,我们这种方式并没有很好地应用到有序链表的特性,所以使用了额外的空间,目前时间复杂度为O(n) 空间复杂度为O(n)
//那就再考虑下怎么不使用额外的空间
其实也比较好想:
public ListNode deleteDuplicates(ListNode head) { //这里您就问了,这是什么节点呢? //这是一个哑节点,没有存储数字的含义,作用就是:能够指向最终的结果。 ListNode dummyNode = new ListNode(0); dummyNode.next = head; ListNode current = dummyNode; while(current.next != null && current.next.next != null){ //如果说当前节点的下一个跟下一个的下一个值相等,则把下一个下一个都移除 if(current.next.val == current.next.next.val){ //看到了吧,把当前值拿出来 int x = current.next.val; //然后在这个循环里,删除current.next的值,如果等于x while(current.next != null && current.next.val == x){ current.next = current.next.next; } } else { current = current.next; } } return dummyNode.next; }
时间复杂度为O(n)、空间复杂度为O(1)