题解 | 删除有序链表中重复的元素-II
删除有序链表中重复的元素-II
https://www.nowcoder.com/practice/71cef9f8b5564579bf7ed93fbe0b2024
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* public ListNode(int val) {
* this.val = val;
* }
* }
*/
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
public ListNode deleteDuplicates (ListNode head) {
// write code here
if(head == null || head.next == null){
return head;
}
ListNode dummy = new ListNode(0);
ListNode pre = dummy;
ListNode left = head,right = head.next;
while(right != null){
if(left.val != right.val){
pre.next = left;
pre = pre.next;
}
while(right != null && right.val == left.val){
right = right.next;
}
if(right != null && right.next != null && right.val != right.next.val){
pre.next = right;
pre = pre.next;
left = right.next;
right = right.next.next;
}else{
if(right == null){
pre.next = null;
}else if(right.next == null){
pre.next = right;
break;
}else{
left = right;
right = right.next;
}
}
}
return dummy.next;
}
}
本题与“删除有序链表中重复的元素-I”类似,不同点就是链表的元素是有序的,因此可以利用该条件,通过比较相邻元素是否相同从而判断是否有重复元素(因为元素有序,所以重复元素只能出现在相邻元素)从而省去哈希表的使用,从而将空间复杂度由O(n)降为O(1)。
思路:利用三指针:pre、left与right,left与right用于判断pre之后(不包括pre)的[left,right]闭区间范围内是否有重复元素。如果有,则将[left,right]内的元素删去,并且将left移动到right+1位置处,right从left+1开始向后移动。
难点:当删除[left,right]这个区间之后,最新的left与right的val值可能也会相同,因此不能在每次删除[left,right]区时就将pre.next指向最新的left并且移动pre为pre.next,将pre向后移动之后,此时就会遗失之前的pre了。因此更改pre.next的指向并且将pre向后移动是有条件的:当left.val != right.val时,才能将pre.next指向left,并且移动pre。
#三指针##双指针##链表#