方法一:
这种方法是自己想起来的,只用到了一个指针,因此相较于使用两个指针的情况,处理时要来的麻烦些。使用两个指针的方法简便易行,所以在实际中还是比较推荐第二种,但是这种方法仍有些需要注意之处。首先,在while循环中,注意条件pstart != null和pstart.next != null所带来的不同,在前者的情况下,最后一个元素是访问不到的,而在后者的情况下,最后一个元素仍然可以得到访问;其次,在处理问题的时候最先要想到最为极端的情况,在这一道题目里面,也就是如果给出的链表为空要怎么办,所以要首先处理这个问题;第三,虽然这种方法比较繁琐,但是想到这种方法的思维流程值得注意,先考虑输入最为极端的情况,将这种情况处理掉,接着思考输入在一般情况下的情况,并且根据这种情况写出程序的大致框架,最后想一下输入的特殊情况,比如头部,尾部,全部相等的情况,再根据这些内容调整所写出的程序
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode deleteDuplicates(ListNode head) {
//Attention: Always check extreme situation
if(head == null){
return head;
}
//singly-linked list, no going back, use a temp pointer
ListNode pstart = head;
while(pstart.next != null){
//check duplicate
if(pstart.val == pstart.next.val){
//delete duplicate
if(pstart.next.next == null){
pstart.next = null;
//[1, 2, 2]
break;
}else{
pstart.next = pstart.next.next;
//[1, 1, 1]
continue;
}
}
//move pointer
pstart = pstart.next;
}
return head;
}
}
方法二:
这种方法使用了两个指针,代码很简洁而且一旦了解这种思想则比较容易模仿,在此要特别注意第二种方法,将这种思路以及代码记下来作为代码块,在以后的题目里用上
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode deleteDuplicates(ListNode head) {
//Attention: Always check extreme situation
if(head == null) return head;
for(ListNode prev = head, cur = head.next; cur != null; cur = prev.next){
//check duplicate
if(prev.val == cur.val){
//delete
prev.next = cur.next;
}else{
//update pointers
prev = cur;
}
}
return head;
}
}