Remove Duplicates from Sorted List解题报告

---恢复内容开始---

 Remove Duplicates from Sorted List

题目意图:删除掉linked list里面的重复的元素

思路: 1. 对于重复的点,会保留当前数字第一次出现的点,所以返回结果的起始点与当前起始点为同一个点,不需要新建dummy node来表示起始点。
      2. 用一个pre pointer遍历整个linked list,如果当前点与下一个点一致则删除下一个点。

我的代码:

 1  public static ListNode deleteDuplicates(ListNode head) { 
 2         // write your code here
 3         if (head == null) {
 4             return head;
 5         }
 6         
 7         ListNode pre = new ListNode(0);
 8         pre = head;
 9         while (pre != null && pre.next != null) {
10             while(pre.next != null && pre.next.val == pre.val){
11                 pre.next = pre.next.next;
12             }
13             pre = pre.next;
14         }
15         return head;
16     }  

九章代码:

public ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return null;
        }

        ListNode node = head;
        while (node.next != null) {
            if (node.val == node.next.val) {
                node.next = node.next.next;
            } else {
                node = node.next;
            }
        }
        return head;
    }

反思:1. 对于一维的linked list,只需要分当前点和下一个点是否相同,做一次遍历就好。

   2. 对于我的方法,在内层while之行删除所有可能与当前点一致点后,把pre指针往后移。注意要判断是否已经到linked list的结尾。

 Remove Duplicates from Sorted List II

 题目意图:删除所有重复的点
思路:1. 对于重复的点,所有与当前点相等的点全部删除,包括当前点。这样就不能保证head与返回时候的head一致。因为head可能被删除,所以需要建立一个dummy node 放在当前的head前面。
   2.因为当数相等时,要删除掉比较者和被比较者,故不能只通过一次循环两两比较。(aaa形式,删掉aa,没法判断。 如果用临时变量记录pre值,那么第一次删除2个点,后来每一次删除1个点,不好控制)所以,用2层while的结构,如果碰到相同的,那么用第二层循环把所有相同的值都删掉。
我的代码:
 1 public class Solution {
 2     public static ListNode deleteDuplicates(ListNode head) {
 3         if (head == null) {
 4             return head;
 5         }
 6         ListNode dummy = new ListNode(0);
 7         dummy.next = head;
 8         ListNode pre = new ListNode(0);
 9         pre = dummy; 
10         while (head.next != null) {
11             if (head.val == head.next.val) {
12                 while (head.next != null && head.val == head.next.val) {
13                     head.next = head.next.next;
14                 }
15                 pre.next = head.next;
16                 if(pre.next != null){
17                     head = pre.next;
18                 }
19             } else {
20                     head = head.next;
21                     pre = pre.next;
22             }
23         }
24             return dummy.next;
25     }    
26 }

 用了dummy和pre pointer,dummy pointer用于存储整个linked list删除后的头,pre pointer用于存储内部循环被对比节点的前一个点(eg: abc 循环到b与c比较时,pre纪录a,防止b和c相同,同时被删除)。

删除时候,外部循环用于遍历整个linked list。内部循环用于对制定节点遍历后面的所有节点,如果相同删除后面的这个节点,循环中每次只删除后面的这一个节点。对于被比较的这个节点,在内部while循环结束时删除,同时pre pointer不变,更新head节点。

九章代码:

public class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null)
            return head;
        
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        head = dummy;

        while (head.next != null && head.next.next != null) {
            if (head.next.val == head.next.next.val) {
                int val = head.next.val;
                while (head.next != null && head.next.val == val) {
                    head.next = head.next.next;
                }            
            } else {
                head = head.next;
            }
        }
        
        return dummy.next;
    }
}

九章的代码中内部循环的方式更加简单

用head pointer 当作pre pointer,对head->next和head->next 做对比

在外部循环一旦确定2个值相等,用一个val的临时变量纪录当前的值,然后从head->next开始一个一个的向后删除。这样做避免了在内部循环时候需要一一个删除,最后删除当前被比较的node的情况。 因此在内部循环,始终只考虑是否相等,一次删除一个节点。

反思: 多重循环时候,尽量保持一重循环只做一件事情,使得代码简化。对于我的方法中的比较数和被比较数均可通过一个point的next和next next来表示,可以不用2个变量。

 

   

 

 

 

 

 

---恢复内容结束---

posted @ 2016-04-16 04:30  毛线刷题笔记  阅读(165)  评论(0编辑  收藏  举报