leetcode83-刪除排序鏈表中的重復元素


leetcode(使用的是中文網站:領扣):83 

給定一個排序鏈表,刪除所有含有重復數字的節點,只保留原始鏈表中 沒有重復出現 的數字。

示例 1:

輸入: 1->2->3->3->4->4->5
輸出: 1->2->5

示例 2:

輸入: 1->1->1->2->3
輸出: 2->3

 
一開始沒有看到排序鏈表這個條件,所以解法有一點麻煩
解法一:
思路:再創建一個鏈表B,然后遍歷原來的鏈表A,將A中的元素添加到B的鏈表尾部。
每次向B中添加元素時都檢查一下B中是否已經存在這個元素,若存在,則不添加。代碼如下:
package leetcode.LinkedList83;

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null) {
            return null;
        }
        //原鏈表的當前節點
        ListNode cur = head.next;

        //創建一個新的鏈表
        ListNode newHead = new ListNode(head.val);
        ListNode newList_cur = newHead;

        while(cur!=null){
            //如果新的鏈表中沒有這個節點,那么就添加進去
            if(!contains(newHead,cur.val)){
                newList_cur.next = new ListNode(cur.val);
                newList_cur = newList_cur.next;
            }
            cur = cur.next;
        }
        return newHead;
    }

    //檢測鏈表中是否包含某個元素
    boolean contains(ListNode head,int val){
        while(head != null){
            if(head.val == val){
                return true;
            } else {
                head = head.next;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        int arr[] = {1,2,3,4,3,5,6};
        ListNode head = new ListNode(arr);
        System.out.println(head);

        ListNode ret = (new Solution()).deleteDuplicates(head);
        System.out.println("最終結果:"+ret);
    }
}

 

這里為了測試代碼,我們這里可以寫一個將數組轉化成鏈表的函數

本地測試用代碼(后面的代碼測試也是用的這個):

package leetcode.LinkedList83;

/**
 * 用於本地測試
 */
class ListNode {
  int val;
  ListNode next;
  ListNode(int x) { val = x; }


  // 鏈表節點的構造函數
  // 使用arr為參數,創建一個鏈表,當前的ListNode為鏈表頭結點
  ListNode(int[] arr){
    if(arr == null || arr.length == 0){
      throw new IllegalArgumentException("arr can not be empty");
    }

    this.val = arr[0];
    ListNode cur = this;
    for (int i = 1; i < arr.length; i++) {
      cur.next = new ListNode(arr[i]);
      cur = cur.next;
    }
  }

  @Override
  public String toString(){
    StringBuilder sb = new StringBuilder();
    ListNode cur = this;
    while(cur != null){
      sb.append(cur.val);
      sb.append("->");
      cur = cur.next;
    }
    sb.append("NULL");
    return sb.toString();
  }
}

 

解法二(這里才用到題目的已經排序的條件):

思路:使用遞歸,在遞推之后回歸的過程中我們可以比較當前鏈表和子鏈的值是否相等,相等的話就直接返回子鏈,否則就返回當前鏈表。

鏈表的遞歸,可以想象成不斷的把問題交給子鏈去解決,最后返回的時候也是不斷的返回子鏈的結果。

package leetcode.LinkedList83;
public class Solution2 { public ListNode deleteDuplicates(ListNode head) { if(head == null || head.next == null) { return head; } else { // ListNode res = deleteDuplicates(head.next); // if(head.val == head.next.val){ // return res; // } else { // head.next = res; // return head; // } head.next = deleteDuplicates(head.next); return head.val == head.next.val ? head.next:head; } } public static void main(String[] args) { int arr[] = {1,2,3,3,5,6}; ListNode head = new ListNode(arr); System.out.println(head); ListNode ret = (new Solution2()).deleteDuplicates(head); System.out.println("最終結果:"+ret); } }

簡單的畫個圖表示一下(用res更好理解一點):

 

 最后是官方給出的使用迭代的方法:

解法三:

思路:每一次都比較當前節點和下一個節點的值,如果不同,就將當前節點后移,如果相同,就不改變當前節點,直至下一個節點的值與當前節點的值不相等。

public ListNode deleteDuplicates(ListNode head) {
    ListNode current = head;
    while (current != null && current.next != null) {
        if (current.next.val == current.val) {
            current.next = current.next.next;
        } else {
            current = current.next;
        }
    }
    return head;
}

 

剛剛開始接觸leetcode,許多解法都還沒怎么分析復雜度,所以自己的解法也不一定是什么好的方法,大家簡單看下思路就好。
錯漏之處請在評論區之處。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM