剑指offer——删除链表中重复的结点
两种方法:
法一:不太好
借助于HashMap,将每个结点均加入map中,key为结点值,value为boolean类型,为true表示加入了一次,false表示加入了两次及以上,
在加入前判断map中是否已存在结点的值,
若不存在,则加入(node.val, true)
若存在,则加入(node.val, false)
然后再次遍历链表,同时查找map中的key值,若为true,则放入新结点中,否则忽略
public class Solution { public ListNode deleteDuplication(ListNode pHead){ if(pHead == null || pHead.next == null) return pHead; HashMap<Integer, Boolean> map = new HashMap<>(); ListNode node = pHead; while(node != null){ if(map.containsKey(node.val)){ map.put(node.val, false); }else{ map.put(node.val, true); } node = node.next; } for(HashMap.Entry<Integer, Boolean> entry : map.entrySet()){ } ListNode head = new ListNode(0); node = head; while(pHead != null){ if(map.get(pHead.val)){ node.next = pHead; node = node.next; } pHead = pHead.next; } node.next = null; node = head; while(node != null){ node = node.next; } return head.next; } }
法二:采用
newHead,(新的头结点,用来返回)
newNext(用来将新结点后面结点连接起来),
先将两个结点均指向新的new ListNode(0),
遍历链表的时候,判断链表的当前结点及下一个结点的值,
若相等,则记录下当前结点的值val,并且开始遍历,知道当前结点值不为val时,出来,继续判断(不用记录当前结点,因为要将重复的结点全部删除)
若不相等,则newNext = 当前结点的值
最后一点需要注意的是,当最后一个结点是不重复的时候,是没法判断的,所以newNext = pHead即可(即是最后一个节点是重复的,那么在上面的循环中,已经将其遍历过,现在pHead指向null)
public class Solution { public ListNode deleteDuplication(ListNode pHead){ if(pHead == null || pHead.next == null) return pHead; ListNode newHead = new ListNode(0); ListNode newNext = newHead; while(pHead != null && pHead.next != null){ if(pHead.val == pHead.next.val){ int val = pHead.val; while(pHead != null && pHead.val == val){ pHead = pHead.next; } }else{ newNext.next = pHead; newNext = newNext.next; pHead = pHead.next; } } newNext.next = pHead; return newHead.next; } }