鏈表基礎題大全(五):阿里巴巴算法 - 保留有序單鏈表中的重複元素(只保留一次)

(尊重勞動成果,轉載請註明出處:https://yangwenqiang.blog.csdn.net/article/details/105694552冷血之心的博客)

這段時間完成了職業生涯第一次跳槽,對算法題目有了一個更深的認識和理解,這裏將鏈表常見的面試題目以及解法補充完善。

鏈表基礎題大全(一)

鏈表基礎題大全(二)

鏈表基礎題大全(三):奇偶鏈表和旋轉鏈表

鏈表基礎題大全(四):單鏈表相加 & 複製帶隨機指針的鏈表 &判斷迴文鏈表

鏈表基礎題大全(五):保留有序單鏈表中的重複元素(只保留一次)


今天我們來看一個更加陰險狡詐的單鏈表題目吧,大多數情況下,我們見到的單鏈表題目都是這樣的:單鏈表刪除(Delete)或者去除(Remove)節點面試題總結

也就是說,在一個單鏈表中,題目會要求我們對重複元素進行一個刪除,要不全部刪除,要麼只保留一個重複元素,或者也可以說刪除具有指定val的節點。

我們今天來看一個單鏈表題目:

給定一個有序鏈表,保留鏈表中重複出現的元素,並且只保留一次,如給定鏈表1->1->1->2->3->3->4. 結果爲1->3。請寫出一個高效的算法。

思路:

之前我們遇到的大多數題目,基本都是要求刪除鏈表中的重複元素,包括全部刪除或者只保留一個重複元素,這個題目剛好相反,將所有的不重複元素刪除掉,並且只保留一次重複元素。

因爲是有序的單鏈表,所以我們比較cur和cur.next的value是否相等?如果相等的話,將cur放到將要返回的鏈表中reHead中,並且需要判斷rreHead鏈表中的最後一個元素reCur是否等於當前節點cur的值,以此來決定是否要將當前節點放入reHead中!

說白了,就是節點的斷開和續上的操作!

代碼實現如下:


public class Test {
    public static void main(String[] args) {
        ListNode node1 = new ListNode(0);
        ListNode node2 = new ListNode(0);
        ListNode node3 = new ListNode(1);
        ListNode node4 = new ListNode(2);
        ListNode node5 = new ListNode(3);
        ListNode node6 = new ListNode(3);
        ListNode node7 = new ListNode(4);
        ListNode node8 = new ListNode(5);
        ListNode node9 = new ListNode(5);

        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        node7.next = node8;
        node8.next = node9;

        ListNode resNode = saveDumpNodes(node1);

        while (resNode != null) {
            System.out.println(resNode.val);
            resNode = resNode.next;
        }
    }

    private static ListNode saveDumpNodes(ListNode root) {
        if (root == null || root.next == null) {
            return null;
        }
        boolean flag = false;
        if (root.val == root.next.val) { // 特殊情況判斷
            flag = true;
        }

        ListNode reHead = root; // 表示結果鏈表的頭節點
        ListNode reCur = root;  // 表示結果鏈表的尾節點
        ListNode cur = root;    // 當前正在處理的節點
        while (cur.next != null) {
            if (cur.val == cur.next.val) {   // 判斷是否是重複節點
                if (reCur.val != cur.val) {  // 是否可以將當前節點放入結果鏈表中
                    reCur.next = cur;   // 接下來的代碼塊是更新reCur和cur的相關邏輯
                    cur = cur.next;     // 主要還是斷開和續上各個節點
                    reCur = reCur.next;
                    reCur.next = null;
                    continue;
                }

            }
            cur = cur.next;
        }
        // 是否需要特殊處理
        return flag ? reHead : reHead.next;

    }

}

class ListNode {
    int val;
    ListNode next;

    public ListNode(int val) {
        this.val = val;
    }
}

總結:

這是阿里巴巴新零售供應鏈-Java崗位社招面試的算法題目,在遇到的時候,也給筆者造成了一定的困擾,希望對大家有所幫助,如果你有更好的解法,也請告訴我哦~


注意啦,注意啦~

歡迎大家關注我的牛客專欄《Java開發崗面試題全解析》 ,點擊圖片查看詳情。

Java開發崗高頻面試題全解析,專欄共計32節,已經全部更新完畢。

專欄分9個模塊來對Java崗位面試中的知識點進行解析,包括通用面試技能,Java基礎,Java進階,網絡協議,常見框架以及算法,設計模式等。

專欄串點成面的解析每個面試題背後的技術原理,由淺入深,循序漸進,力爭讓大家掌握面試題目的背後的技術原理,摒棄背題模式的陋習。


如果對你有幫助,記得點贊哈,歡迎大家關注我的博客,關注公衆號(文強的技術小屋),學習更多技術知識,一起遨遊知識海洋~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章