【算法】【线性表】【链表】删除排序链表中的重复元素 II
1 题目
给定一个已排序的链表的头 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
- 题目数据保证链表已经按升序 排列
2 解答
跟上一个题有一点类似,但还是不一样,它重复的元素要全部删除掉哈:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode deleteDuplicates(ListNode head) { // 如果链表为空或者next为空 直接返回 if (head == null || head.next == null) { return head; } // 先加一个头节点,方便逻辑处理 ListNode preHead = new ListNode(0); preHead.next = head; ListNode node = preHead; while (node != null) { // 因为我们加了一个头节点,那么当前的node肯定是需要保留的 这个理解的吧 // 然后我们后边的两个节点 ListNode nextOneNode = node.next; // 如果后边的两个节点 有一个为空 都可以break 说明后边没重复的了 if (nextOneNode == null) break; ListNode nextTwoNode = nextOneNode.next; if (nextTwoNode == null) break; // flag 表示 node 后的第一个节点要不要删除 boolean flag = false; // 从第二个节点开始遍历 while (nextTwoNode != null) { // 如果他跟第一个节点的 val 一样 说明重复了 if (nextTwoNode.val == nextOneNode.val) { // 设置 flag = true 遍历完需要把第一个节点也删除 flag = true; // 删除第二个节点 nextOneNode.next = nextTwoNode.next; // 继续向后遍历删除 看看还有没有与第1个节点一样的 val nextTwoNode = nextTwoNode.next; // 继续 continue; } // 不相等了,说明与第一个节点一样的都已经删除完了 直接跳出 break; } // flag = true 说明第一二节点有重复的,这里把第一个节点也删除掉 if (flag) { node.next = nextOneNode.next; continue; } // 继续向后遍历 node = node.next; } return preHead.next; } }
现在链表的题就有点得心应手了,前几天做链表的题,那家伙一个简单的题,自己把自己绕的,一个多小时想不出来,现在十来分钟两道题,对于链表我就喜欢前边加个空头节点,感觉思路就清晰点儿,加油。