算法學(xué)習(xí)筆記之初級鏈表

記錄一下最近刷的比較有意思的題

1. 環(huán)形鏈表

給定一個(gè)鏈表,判斷鏈表中是否有環(huán)。

進(jìn)階

你能否不使用額外空間解決此題?

我的思路與解答(1ms):

首先理解環(huán)形鏈表的概念,我開始以為只有一種,就是頭尾相連的鏈表就是環(huán)形鏈表,如下圖;


圖1

但其實(shí)還有一種比較特殊一點(diǎn)的環(huán)形鏈表,如下圖;


圖2
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null) return false;
        /** 
        *  主要思路:用雙指針解法,slow和fast,都從頭部開始
        *  slow每次走一步,fast每次走兩步
        *  這樣不論是頭尾相連的環(huán)形鏈表還是特殊的環(huán)形鏈表
        *  在若干步后slow和fast會(huì)相遇
        */
        ListNode slow = head;
        ListNode fast = head;
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
            if(fast.next != null){
                fast = fast.next;
            }else{
                return false;
            }
            if(slow.equals(fast)){
                return true;
            }
        }
        return false;
    }
}

小結(jié):

一開始只想到了頭尾相連的鏈表,去搜索了相關(guān)概念后才知道原來還有另一種,但是這題做起來思路還是比較明確。

2. 合并兩個(gè)有序鏈表

將兩個(gè)有序鏈表合并為一個(gè)新的有序鏈表并返回。新鏈表是通過拼接給定的兩個(gè)鏈表的所有節(jié)點(diǎn)組成的。

示例:

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

我的思路與解答(11 ms):

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1 == null && l2 == null) return null;
        if(l1 == null) return l2;
        if(l2 == null) return l1;
        ListNode head;
        ListNode p1;
        ListNode p2;
        ListNode temp;
        
        // 首先對比兩個(gè)鏈表頭部的值的大小,小的鏈表為最終返回的鏈表,即將頭部大的拆開插入小的鏈表
        if(l1.val <= l2.val){
            head = l1;
            p1 = l1;
            p2 = l2;
        }else{
            head = l2;
            p1 = l2;
            p2 = l1;
        }
        
        /**
        *  進(jìn)入循環(huán),當(dāng)判斷p2指向的結(jié)點(diǎn)的值大于等于p1所指向且小于p1的下個(gè)結(jié)點(diǎn)的值時(shí)
        *  將p2所指向的結(jié)點(diǎn)插到p1之后,并將p1指向被插入的結(jié)點(diǎn)
        *  當(dāng)p1或p2為最后一個(gè)結(jié)點(diǎn)時(shí)跳出循環(huán)
        */ 
        while(p1.next != null && p2.next != null){
            if(p2.val >= p1.val) {
                if(p1.next.val > p2.val) {
                    temp = p1.next;
                    p1.next = p2;
                    l2 = p2.next;
                    p2.next = temp;
                    p1 = p2;
                    p2 = l2;
                    continue;
                }
                p1 = p1.next;
            }
        }
        
        /**
        *  這時(shí)會(huì)有兩張情況:
        *  1. p2為最后一個(gè)結(jié)點(diǎn),只需再進(jìn)行一次循環(huán),將p2插入鏈表
        *  2. p1為最后一個(gè)結(jié)點(diǎn),說明鏈表的最大的值都沒有比p2所指向的結(jié)點(diǎn)的值大,只需將p2插到鏈表的最后即可
        *     因?yàn)檫@時(shí)p1指向的是最后一個(gè)結(jié)點(diǎn),所以直接 p1.next = p2 即可
        */
        if(p2.next == null){
            while(p1.next != null){
                if(p2.val >= p1.val){
                    if(p1.next.val > p2.val) {
                        temp = p1.next;
                        p1.next = p2;
                        l2 = p2.next;
                        p2.next = temp;
                        p1 = p2;
                        p2 = l2;
                        return head;
                    }
                    p1 = p1.next;
                }
            }
        }
        
        if(p1.next == null){
            p1.next = p2;
        }
        
        return head;
        
    }
}

小結(jié):

這題第一次做的時(shí)候思路很亂,做了一個(gè)晚上都沒做出來,第二天再做的時(shí)候理清思路10分鐘就做出來了,事實(shí)證明做題思路很重要

3. 總結(jié)

鏈表類的題目尤其需要思路明確,有一點(diǎn)錯(cuò)誤就容易發(fā)生空指針異常。

本文作者:RoNnx
博客鏈接:http://ronnx.top/2018/06/17/20180004/
版權(quán)聲明:本作品采用「知識(shí)共享署名-非商業(yè)性使用-相同方式共享 4.0 國際許可協(xié)議 進(jìn)行許可」,轉(zhuǎn)載請注明出處!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 搞懂單鏈表常見面試題 Hello 繼上次的 搞懂基本排序算法,這個(gè)一星期,我總結(jié)了,我所學(xué)習(xí)和思考的單鏈表基礎(chǔ)知識(shí)...
    醒著的碼者閱讀 4,742評論 1 45
  • 鏈表刪除[203] Remove Linked List Elements[19] Remove Nth Node...
    野狗子嗷嗷嗷閱讀 6,442評論 4 35
  • (一)LeetCode206.反轉(zhuǎn)鏈表 題目描述: 反轉(zhuǎn)一個(gè)單鏈表。 代碼實(shí)現(xiàn) (二)LeetCode160. 相...
    Jarily閱讀 1,491評論 0 5
  • 轉(zhuǎn)載請注明出處:http://m.itdecent.cn/p/c65d9d753c31 在上一篇博客《數(shù)據(jù)結(jié)構(gòu)...
    Alent閱讀 3,611評論 4 74
  • (這是一篇小學(xué)生的流水賬作文 啊哈哈 慎點(diǎn)) 直到4月底,實(shí)習(xí)生活的煩悶讓我決定再次拎起腳步向向往已久的地方出發(fā)—...
    北巷子貓閱讀 696評論 0 1

友情鏈接更多精彩內(nèi)容