2019 算法面試相關(leetcode)--數(shù)組和鏈表

2019 iOS面試題大全---全方面剖析面試
2018 iOS面試題---算法相關
1、七種常見的數(shù)組排序算法整理(C語言版本)
2、2019 算法面試相關(leetcode)--數(shù)組和鏈表
3、2019 算法面試相關(leetcode)--字符串
4、2019 算法面試相關(leetcode)--棧和隊列
5提岔、2019 算法面試相關(leetcode)--優(yōu)先隊列
6、2019 算法面試相關(leetcode)--哈希表
7笋敞、2019 算法面試相關(leetcode)--樹碱蒙、二叉樹、二叉搜索樹
8夯巷、2019 算法面試相關(leetcode)--遞歸與分治
9赛惩、2019 算法面試相關(leetcode)--貪心算法
10、2019 算法面試相關(leetcode)--動態(tài)規(guī)劃(Dynamic Programming)
11趁餐、2019 算法面試相關(leetcode)--動態(tài)規(guī)劃之背包問題


反轉鏈表
兩兩交換鏈表中的節(jié)點
環(huán)形鏈表
環(huán)形鏈表 II

鏈表和數(shù)組作為算法中的兩個基本數(shù)據(jù)結構喷兼,在程序設計過程中經(jīng)常用到。盡管兩種結構都可以用來存儲一系列的數(shù)據(jù)后雷,但又各有各的特點季惯。
數(shù)組的優(yōu)劣勢:可以方便的遍歷查找需要的數(shù)據(jù),時間復雜度為O(1)臀突。這種時間上的便利性勉抓,是因為數(shù)組在內存中占用了連續(xù)的空間,在進行類似的查找或者遍歷時候学,本質是指針在內存中的定向偏移琳状。然而,當需要對數(shù)組成員進行添加和刪除的操作時盒齿,數(shù)組內完成這類操作的時間復雜度則變成了O(n)
鏈表的優(yōu)劣勢:在某些操作上比數(shù)組更加高效念逞,例如當進行插入和刪除操作時,鏈表操作的時間復雜度僅為O(1)边翁。因為鏈表在內存中不是連續(xù)存儲的翎承,所以可以充分利用內存中的碎片空間。
提到數(shù)組就不得不提到數(shù)組的排序:七種常見的數(shù)組排序算法整理(C語言版本)

  • 下面主要針對leetcode上關于鏈表的一些題目符匾,這里我是使用的JavaScript
function ListNode(val) {
    this.val = val;
    this.next = null;
}

一叨咖、3種方法實現(xiàn)反轉鏈表
反轉一個單鏈表。

示例:

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


  • 1、遞歸實現(xiàn)
    遞歸的方法其實是非常巧的甸各,它利用遞歸走到鏈表的末端垛贤,然后再更新每一個node的next 值 ,實現(xiàn)鏈表的反轉趣倾。而newhead 的值沒有發(fā)生改變聘惦,為該鏈表的最后一個結點,所以儒恋,反轉后善绎,我們可以得到新鏈表的head。
var reverseList = function(head) {
   
    if (!head || !head.next) return head;
    
    let newHead = reverseList(head.next);
    
    head.next.next = head;
    
    head.next = null;
    
    return newHead;
};
  • 2诫尽、新建鏈表禀酱,頭節(jié)點插入法
    新建一個頭結點,遍歷原鏈表牧嫉,把每個節(jié)點用頭結點插入到新建鏈表中剂跟。最后,新建的鏈表就是反轉后的鏈表酣藻。
var reverseList = function(head) {

    if (!head || !head.next) return head;

    let lastNode = new ListNode(head.val), curNode;

    let node = head.next;

    while (node) {

        curNode = new ListNode(node.val);

        curNode.next = lastNode;

        lastNode = curNode;

        node = node.next;
    }

    return curNode;
};
  • 3浩聋、直接反轉
    把當前鏈表的下一個節(jié)點指向當前結點,直至循環(huán)結束
var reverseList = function(head) {
    
    if(!head || !head.next) return head

    let pre = head, cur, last = head.next;

    head.next = null;

    while (last) {

        cur = last;

        last = cur.next;

        cur.next = pre;

        pre = cur;
    }

    return cur;
};

二 臊恋、兩兩交換鏈表中的節(jié)點
給定一個鏈表衣洁,兩兩交換其中相鄰的節(jié)點,并返回交換后的鏈表抖仅。

示例:

給定 1->2->3->4, 你應該返回 2->1->4->3.
說明:

你的算法只能使用常數(shù)的額外空間坊夫。
你不能只是單純的改變節(jié)點內部的值,而是需要實際的進行節(jié)點交換撤卢。


記錄相鄰兩個結點cur和last环凿,以及之前的結點prev,然后去進行反轉相鄰的兩個結點放吩,依次循環(huán)到最后

var swapPairs = function(head) {
    
    if(!head || !head.next) return head
    
    let res = head.next

    let cur = head

    let prev = last = null

    while(cur && cur.next){

        last = cur.next

        cur.next = last.next

        last.next = cur

        if(prev) prev.next = last

        prev = cur

        cur = cur.next
    }

    return res
};

三智听、環(huán)形鏈表
給定一個鏈表,判斷鏈表中是否有環(huán)渡紫。

為了表示給定鏈表中的環(huán)到推,我們使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos-1惕澎,則在該鏈表中沒有環(huán)莉测。

示例 1:

輸入:head = [3,2,0,-4], pos = 1
輸出:true
解釋:鏈表中有一個環(huán),其尾部連接到第二個節(jié)點唧喉。

image

示例 2:

輸入:head = [1,2], pos = 0
輸出:true
解釋:鏈表中有一個環(huán)捣卤,其尾部連接到第一個節(jié)點忍抽。

image

示例 3:

輸入:head = [1], pos = -1
輸出:false
解釋:鏈表中沒有環(huán)。

image

進階:

你能用 O(1)(即董朝,常量)內存解決此問題嗎鸠项?


正常鏈表都是有頭有尾的,而環(huán)形鏈表則是沒有尾的子姜,它的尾會指向其中一個結點pos(不一定是指向頭結點)祟绊,也就是環(huán)形鏈表,該題目就是來判斷一個鏈表是否是環(huán)形鏈表闲询。
正常來說久免,對鏈表進行循環(huán)浅辙,如果存在尾指針扭弧,即某結點指向null,即可證明該鏈表不是環(huán)形鏈表记舆。但如果對環(huán)形鏈表進行循環(huán)的話鸽捻,會造成死循環(huán),這樣就沒辦法確定是鏈表足夠長還是該鏈表是環(huán)形鏈表泽腮。

  • 1御蒲、比較容易想到的就是利用數(shù)組或集合:循環(huán)鏈表,將結點依次保存在集合中诊赊,如果下個結點已經(jīng)在集合中存在厚满,則說明是環(huán)形鏈表。如果循環(huán)到最后指向null碧磅,則非環(huán)形鏈表碘箍。
var hasCycle = function(head) {
    
    let set = new Set()

    while(head){

        if(set.has(head)) return true

        set.add(head)

        head = head.next
    }

    return false
};

但題目有要求讓用o(1)空間復雜度解決,但這種方法空間復雜度很明顯是o(n),不符合要求

  • 2鲸郊、還有一種比較巧妙的方法:快慢指針

快慢指針中的快慢指的是移動的步長丰榴,即每次向前移動速度的快慢。例如可以讓快指針每次沿鏈表向前移動2秆撮,慢指針每次向前移動1次四濒。此外還有其他不少巧妙的應用。

這里使用快慢指針职辨,slow每次走一步盗蟆,fast每次走兩步,如果不是環(huán)形鏈表舒裤,則會一直循環(huán)下去姆涩,永遠不會相遇,直至循環(huán)結束惭每。
反之如果這兩個指針相遇骨饿,則說明該鏈表是環(huán)形鏈表亏栈。

var hasCycle = function(head) {
    
    let slow = fast = head

    while(fast && fast.next){

        slow = slow.next

        fast = fast.next.next

        if(slow == fast) return true
    }

    return false
};

四、 環(huán)形鏈表 II
給定一個鏈表宏赘,返回鏈表開始入環(huán)的第一個節(jié)點绒北。 如果鏈表無環(huán),則返回 null察署。

為了表示給定鏈表中的環(huán)闷游,我們使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1贴汪,則在該鏈表中沒有環(huán)脐往。
示例 1:

輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 1
解釋:鏈表中有一個環(huán),其尾部連接到第二個節(jié)點扳埂。

image

示例 2:

輸入:head = [1,2], pos = 0
輸出:tail connects to node index 0
解釋:鏈表中有一個環(huán)业簿,其尾部連接到第一個節(jié)點。

image

示例 3:

輸入:head = [1], pos = -1
輸出:no cycle
解釋:鏈表中沒有環(huán)阳懂。

image

說明:不允許修改給定的鏈表梅尤。


題目意思是如果鏈表是環(huán)形鏈表,就返回交點(鏈表尾連接到鏈表中的位置)在該鏈表中的位置岩调,否則返回null
如果是用方法1使用數(shù)組保存結點巷燥,很容易就可以做到,這里不再贅述
快慢指針的話号枕,首先先循環(huán)一次缰揪,判斷是否是環(huán)形鏈表,不是的話直接返回null葱淳。是的話钝腺,則記錄下相遇點。然后head開始跑蛙紫,同時fast指針繼續(xù)從相遇點跑拍屑,則head必然會和fast指針在環(huán)形鏈表交點相遇。

var detectCycle = function(head) {
    
    let slow = fast = head

    while(fast && fast.next){

        slow = slow.next

        fast = fast.next.next

        if(slow == fast) {
        
            while(fast != head){
        
                head = head.next
        
                fast = fast.next
            }

            return head
        }
    }

    return null
};
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末坑傅,一起剝皮案震驚了整個濱河市僵驰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唁毒,老刑警劉巖蒜茴,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浆西,居然都是意外死亡粉私,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門近零,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诺核,“玉大人抄肖,你說我怎么就攤上這事〗焉保” “怎么了漓摩?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長入客。 經(jīng)常有香客問我管毙,道長,這世上最難降的妖魔是什么桌硫? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任夭咬,我火速辦了婚禮,結果婚禮上铆隘,老公的妹妹穿的比我還像新娘卓舵。我一直安慰自己,他們只是感情好咖驮,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布边器。 她就那樣靜靜地躺著训枢,像睡著了一般托修。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上恒界,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天睦刃,我揣著相機與錄音,去河邊找鬼十酣。 笑死涩拙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的耸采。 我是一名探鬼主播兴泥,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼虾宇!你這毒婦竟也來了搓彻?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤嘱朽,失蹤者是張志新(化名)和其女友劉穎旭贬,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搪泳,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡稀轨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了岸军。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奋刽。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓦侮,死狀恐怖,靈堂內的尸體忽然破棺而出佣谐,到底是詐尸還是另有隱情脏榆,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布台谍,位于F島的核電站须喂,受9級特大地震影響,放射性物質發(fā)生泄漏趁蕊。R本人自食惡果不足惜坞生,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掷伙。 院中可真熱鬧是己,春花似錦、人聲如沸任柜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宙地。三九已至摔认,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宅粥,已是汗流浹背参袱。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留秽梅,地道東北人抹蚀。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓僚害,卻偏偏與公主長得像褂乍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诉濒,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內容