题目描述
- 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
- 地址:牛客地址
问题分析
- 用额外空间:
用map统计次数,次数为1的串成一串 - 不同额外空间,直接链表调整:
- 迭代法
首先设置新建一个头节点,原链表接在之后,这是为了防止原链表的头结点因重复而被删。
然后设置三个指针,preNode,curNode, nextNode:
- curNode.val != nextNode.val:一直往后找,找到不等的那个点,连在preNode 的后面,便完成了这部分的去重,然后curNode指向不等的那个点,继续迭代。
- curNode.val == nextNode.val: 保留curNode,三个指针后移,继续迭代去重
- 递归法
- 思想和迭代法大致一致,但无需新建头结点,具体见实现
经验教训
- 新建一个头结点的技巧,防止原链表头结点被删
- 递归与迭代之前的转换
代码实现
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null) {
return null;
}
HashMap<Integer, Integer> map = new HashMap<>();
ListNode curNode = pHead;
while (curNode != null) {
if (map.containsKey(curNode.val)) {
map.put(curNode.val, map.get(curNode.val) + 1);
}else {
map.put(curNode.val, 1);
}
curNode = curNode.next;
}
curNode = pHead;
ListNode res = new ListNode(1);
ListNode cur = res;
while (curNode != null) {
if (map.get(curNode.val) == 1) {
cur.next = new ListNode(curNode.val);
cur = cur.next;
}
curNode = curNode.next;
}
return res.next;
}
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode preNode = dummy;
ListNode curNode = head;
while (curNode != null) {
int val = curNode.val;
ListNode nextNode = curNode.next;
if (nextNode != null && nextNode.val == val) {
while (nextNode != null && nextNode.val == val) {
nextNode = nextNode.next;
}
preNode.next = nextNode;
curNode = preNode.next;
}else {
preNode = curNode;
curNode = nextNode;
}
}
return dummy.next;
}
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode newList = new ListNode(-1);
newList.next = pHead;
ListNode preNode = newList;
ListNode curNode = pHead;
ListNode nextNode = pHead.next;
while (curNode != null && nextNode != null) {
if (curNode.val == nextNode.val) {
int curVal = curNode.val;
while (nextNode != null && nextNode.val == curVal) {
nextNode = nextNode.next;
}
preNode.next = nextNode;
curNode = nextNode;
nextNode = curNode == null ? null : curNode.next;
}else {
preNode = curNode;
curNode = nextNode;
nextNode = curNode.next;
}
}
return newList.next;
}
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null) {
return pHead;
}
ListNode nextNode = pHead.next;
if (pHead.val == nextNode.val) {
while (nextNode != null && nextNode.val == pHead.val) {
nextNode = nextNode.next;
}
return deleteDuplication(nextNode);
}else {
pHead.next = deleteDuplication(nextNode);
return pHead;
}
}