摘要:拿了小米和美團(tuán)的,要被延期,失效,工作重新找。把準(zhǔn)備過(guò)程紀(jì)錄下來(lái),共勉。注意,有環(huán)的鏈表,此種方法失效。已知兩個(gè)單鏈表和各自有序,把它們合并成一個(gè)鏈表依然有序
寫在最前面
導(dǎo)師貪腐出逃美國(guó),兩年未歸,可憐了我。拿了小米和美團(tuán)的offer,要被延期,offer失效,工作重新找。把準(zhǔn)備過(guò)程紀(jì)錄下來(lái),共勉。
鏈表是最??疾斓臄?shù)據(jù)結(jié)構(gòu)
// 鏈表定義 public class Node{ int val;//數(shù)據(jù)域 Node next;// 指針域 public Node(int val){ this.val = val; } }
基礎(chǔ)題
求單鏈表的長(zhǎng)度
考察鏈表遍歷的方法,時(shí)間復(fù)雜度為o(n)
//求單鏈表長(zhǎng)度,起手判斷鏈表是否為空,非常必要 public static int getListLength(Node head){ //如果鏈表為空,長(zhǎng)度為0 if(null == head){ return 0; } // 開(kāi)始著手辦正事了 int len = 0; Node cur = head; //如果循環(huán)判斷條件不確定,可以先寫邏輯,回頭再定條件 while(null != cur.next){ len++; cur = cur.next; } return len; }
結(jié)點(diǎn)相對(duì)位置關(guān)系,結(jié)點(diǎn)與鏈表的相對(duì)位置關(guān)系
翻轉(zhuǎn)鏈表
鏈表中經(jīng)典解法1,引入兩個(gè)指針,然后確定其相對(duì)位置關(guān)系
迭代法
解題思路:前后兩個(gè)指針,遍歷鏈表,每遍歷一個(gè)結(jié)點(diǎn),前面的指針將指向后面的指針,時(shí)間復(fù)雜度o(n)
public static Node getReverseList(Node head){ if(null == head || null == head.next){ return null; } Node cur = head; Node newHead = null; while(null != cur){ Node preCur = cur; cur = cur.next; preCur.next = newHead; newHead = preCur; } return newHead; }
返回單鏈表倒數(shù)第k個(gè)結(jié)點(diǎn)
兩個(gè)指針,前面的指針超前后面指針k個(gè)位置
public static Node findLastKthNode(Node head,int k){ if(k == 0 || null == head){ return null; } Node p = head; Node q = head; while(k > 0 || p != null){ p = p.next; k--; } if(k > 0 || p == null){ return null; } while(p != null){ q = q.next; p = p.next; } return q; }
查找中間結(jié)點(diǎn)
分析:兩個(gè)指針可以解決,位置相對(duì)關(guān)系是:p指針向前移動(dòng)一步,q指針向前移動(dòng)兩步
public static Node getMiddleNode(Node head){ if(null == head || head.next == null){ return head; } Node p = head; Node q = head; while(p != null){ p = p.next; q = q.next; if(p != null){ p = p.next; } } return q; }
從尾到頭打印單鏈表
public static void printList(Node head){ Stacks = new Stack<>(); Node cur = head; while(cur != null){ s.push(cur); cur = cur.next; } while(!s.empty()){ cur = s.pop(); System.out.print(p.val + " "); } System.out.println(); }
有環(huán)問(wèn)題
判斷一個(gè)單鏈表是否有環(huán)
思路:快慢兩個(gè)指針,如果相遇,則有環(huán)
public static boolean hasCycle(Node head){ Node fast = head; Node slow = head; while(fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ return true; } } return false; }
- **取出有環(huán)鏈表中,環(huán)的長(zhǎng)度**
思路:找到相遇的結(jié)點(diǎn)a后,讓b結(jié)點(diǎn)從a位置向下遍歷,回來(lái)后得到的結(jié)點(diǎn)數(shù),即為環(huán)長(zhǎng)度
//方法:有環(huán)鏈表中,獲取環(huán)的長(zhǎng)度。參數(shù)node代表的是相遇的那個(gè)結(jié)點(diǎn) public int getCycleLength(Node node) { if(node == null){ return 0; } int length = 0; Node cur = node; while(cur != null){ cur = cur.next; length++; if(cur != node){ return length; } } return length; }
判斷兩個(gè)鏈表相交
思路:如果兩鏈接的尾結(jié)點(diǎn)相同,則有環(huán)。注意,有環(huán)的鏈表,此種方法失效。
public static boolean isIntersect(Node head1, Node head2) { Node tail1 = head1; Node tail2 = head2; while(tail1 != null){ tail1 = tail1.next; } while(tail2 != null){ tail2 = tail2.next; } if(tail1 == tail2){ return true; } return false; }
單鏈表中,取出環(huán)的起始點(diǎn)
public Node getCycleStart(Node head, int cycleLength) { Node first = head; Node second = head; for(int i = 0; i < cycleLength; i++){ second = second.next; } while(first != null && second != null){ if(first == second){ return first; } first = first.next; second = second.next; } return null; }
求兩個(gè)單鏈表相交的第一個(gè)節(jié)點(diǎn)
思路:分別求出a鏈表、b鏈表的長(zhǎng)度len1、len2,如果a鏈表比b鏈表長(zhǎng),則a提前移動(dòng)len1-len2距離,然后a、b一起向前移動(dòng),直到引用相同。
public static Node getFirstCommonNode(Node head1, Node head2) { Node tail1 = head1; Node tail2 = head2; int len1 = 1; while(tail1 != null){ tail1 = tail1.next; len1++; } int len2 = 1; while(tail2 != null){ tail2 = tail2.next; len2++; } if(tail1 != tail2){ return null; } Node n1 = head1; Node n2 = head2; if(len1 > len2){ int k = len1 - len2; while(k != 0){ n1 = n1.next; k--; } } if(len1 < len2){ int k = len1 - len2; while(k != 0){ n2 = n2.next; k--; } } while(n1 != n2){ n1 = n1.next; n2 = n2.next; } return n1; }
已知兩個(gè)單鏈表head1和head2各自有序,把它們合并成一個(gè)鏈表依然有序
public static Node mergeSortedList(Node head1, Node head2){ if(head1 == null){ return head2; } if(head2 == null){ return head1; } Node mergeHead = null; if(head1.val < head2.val){ mergeHead = head1; head1 = head1.next; mergeHead.next = null; }else{ mergeHead = head2; head2 = head2.next; mergeHead.next = null; } Node mergeCur = mergeHead; while(head1 != null && head2 != null){ if(head1.val < head2.val){ mergeCur.next = head1; head1 = head1.next; mergeCur = mergeCur.next; mergeCur.next = null; }else{ mergeCur.next = head2; head2 = head2.next; mergeCur = mergeCur.next; mergeCur.next = null; } } if(head1 != null){ mergeCur.next = head1; } if(head2 != null){ mergeCur.next = head2; } return mergeHead; }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/70116.html
摘要:底層實(shí)現(xiàn)是對(duì)象數(shù)組,優(yōu)點(diǎn)是時(shí)間為,缺點(diǎn)是和時(shí)間為,需要留意的是擴(kuò)容的過(guò)程以及的算法本節(jié)參考源碼中放最新的源碼為,組成鏈表或紅黑樹(shù)定義從整體上看,底層的存儲(chǔ)結(jié)構(gòu)是基于數(shù)組和鏈表實(shí)現(xiàn)的。實(shí)現(xiàn)了所謂的線程安全,在很多方法上都加上了。 ArrayList ArrayList底層實(shí)現(xiàn)是對(duì)象數(shù)組,優(yōu)點(diǎn)是set、get時(shí)間為O(1),缺點(diǎn)是add和remove時(shí)間為O(n),需要留意的是擴(kuò)容的過(guò)程以...
摘要:算法名稱描述優(yōu)點(diǎn)缺點(diǎn)標(biāo)記清除算法暫停除了線程以外的所有線程算法分為標(biāo)記和清除兩個(gè)階段首1 回顧我的時(shí)間線 在本文的開(kāi)頭,先分享一下自己的春招經(jīng)歷吧: 各位掘友大家好,我是練習(xí)時(shí)長(zhǎng)快一年的Android小蔡雞,喜歡看源碼,逛掘金,寫技術(shù)文章...... 好了好,不開(kāi)玩笑了OWO,今年春招投了許多簡(jiǎn)歷的,但是被撈的只有阿里,頭條和美團(tuán),一路下來(lái)挺不容易的. 個(gè)人認(rèn)為在春招中運(yùn)氣>性格>三觀>技術(shù)...
摘要:和三個(gè)方法的時(shí)間復(fù)雜度必須為兩種解法,解法一,將最小值存入自有的數(shù)據(jù)結(jié)構(gòu)中,如下所示原本的值最小值解法二,用兩個(gè)棧 堆棧和隊(duì)列統(tǒng)稱線性表 簡(jiǎn)單的線性結(jié)構(gòu) 數(shù)組和鏈表可以實(shí)現(xiàn)這兩種數(shù)據(jù)結(jié)構(gòu) 堆棧 基本理解 DFS 深度優(yōu)先---按深度遍歷 遞歸轉(zhuǎn)非遞歸 隊(duì)列 基本理解 BFS 廣度優(yōu)先---按層序遍歷 出入棧的合法性模擬出入棧的過(guò)程,不是入棧,就是...
摘要:由遍歷結(jié)果反求樹(shù)分析遞歸分治,第一層需要找到相應(yīng)的遍歷結(jié)果,對(duì)數(shù)組來(lái)說(shuō),問(wèn)題轉(zhuǎn)化為找下標(biāo)問(wèn)題對(duì)前序中序遍歷結(jié)果來(lái)說(shuō)前序左右中序左右因此,中序中的下標(biāo)可求,為對(duì)每一層來(lái)說(shuō),左子樹(shù)的長(zhǎng)度為,右子樹(shù)的長(zhǎng)度為,左子樹(shù)前序?yàn)橹?,中序?yàn)橹?,可以? 由遍歷結(jié)果反求樹(shù) 分析:遞歸分治,第一層需要找到相應(yīng)的遍歷結(jié)果,對(duì)數(shù)組來(lái)說(shuō),問(wèn)題轉(zhuǎn)化為找下標(biāo)問(wèn)題 對(duì)前序、中序遍歷結(jié)果來(lái)說(shuō) 前序:[root,[左...
閱讀 3004·2023-04-25 21:23
閱讀 3049·2021-09-22 15:24
閱讀 874·2019-08-30 12:55
閱讀 2108·2019-08-29 18:42
閱讀 2616·2019-08-29 16:27
閱讀 958·2019-08-26 17:40
閱讀 2192·2019-08-26 13:29
閱讀 2620·2019-08-26 11:45