Leetcode:面試題 02.01. 移除重複節點

題目

編寫代碼,移除未排序鏈表中的重複節點。保留最開始出現的節點。

示例1:

 輸入:[1, 2, 3, 3, 2, 1]
 輸出:[1, 2, 3]
示例2:

 輸入:[1, 1, 1, 1, 2]
 輸出:[1, 2]
提示:

鏈表長度在[0, 20000]範圍內。
鏈表元素在[0, 20000]範圍內。
進階:

如果不得使用臨時緩衝區,該怎麼解決?

鏈接:https://leetcode-cn.com/problems/remove-duplicate-node-lcci

解題記錄

  • 通過set記錄出現過的值,重複的跳過
import java.util.HashSet;
import java.util.Set;

/**
 * @author ffzs
 * @describe
 * @date 2020/6/26
 */

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public class Solution {
    public ListNode removeDuplicateNodes(ListNode head) {
        if (head == null) return null;
        ListNode tmp = head;
        Set<Integer> valSet = new HashSet<>();
        valSet.add(tmp.val);
        while (tmp.next!= null) {
            if (valSet.contains(tmp.next.val)) {
                tmp.next = tmp.next.next ;
            }else{
                valSet.add(tmp.next.val);
                tmp = tmp.next;
            }
        }

        return head;
    }
}

在這裏插入圖片描述

優化

  • 因爲本題限定了數取值的大小,可以構建一個定長數組new boolean[20001]來存儲數值的出現情況,這樣避免了使用set包裝器轉換帶來的消耗
/**
 * @author ffzs
 * @describe
 * @date 2020/6/26
 */
public class Solution2 {
    public ListNode removeDuplicateNodes(ListNode head) {
        if (head == null) return null;
        ListNode tmp = head;
        boolean[] valList = new boolean[20001];
        valList[head.val] = true;
        while (tmp.next!= null) {
            if (valList[tmp.next.val]) {
                tmp.next = tmp.next.next ;
            }else{
                valList[tmp.next.val] = true;
                tmp = tmp.next;
            }
        }
        return head;
    }
}

在這裏插入圖片描述

進階

  • 要不使用緩存的話就不能使用set,list這些存儲節點
  • 有個思路是,通過冒泡排序的方法,一邊對比排序一邊去掉重複的值,但是頭結點不能變,是不是不能改變出現順序
  • 還有一個方法就是通過遍歷該節點之後的節點,有重複的直接去掉,不過速度很慢就是了,節省了空間
/**
 * @author ffzs
 * @describe
 * @date 2020/6/26
 */
public class Solution3 {
    public ListNode removeDuplicateNodes(ListNode head) {
        if (head == null) return null;
        ListNode tmp = head;
        while (tmp != null) {
            ListNode t = tmp;
            while (t.next != null) {
                if (t.next.val == tmp.val) {
                    t.next = t.next.next;
                }
                else {
                    t = t.next;
                }
            }
            tmp = tmp.next;
        }
        return head;
    }
}

在這裏插入圖片描述

  • 想了一下如果可以改變出現順序的話,可以從head的下一個開始進行冒泡排序處理,如果該節點的值或head的值和next的值相同,直接刪掉next,如果大於next值,交換位置,如果小於跳到next
  • 不過這裏交換的話需要上一節點,可以使用next和next.next進行比較
  • 重複多次,知道不再發生交換,返回head
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章