【LittleDuck_LeetCodeNote】21 - Merge Two Sorted Lists

更新於 發佈於 閱讀時間約 9 分鐘

Question and Hints

You are given the heads of two sorted linked lists list1 and list2.
Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the first two lists.
Return the head of the merged linked list.
Example 1:
Input: list1 = [1,2,4], list2 = [1,3,4]
Output: [1,1,2,3,4,4]
Example 2:
Input: list1 = [], list2 = []
Output: []
Example 3:
Input: list1 = [], list2 = [0]
Output: [0]
Constraints:
  • The number of nodes in both lists is in the range [0, 50].
  • 100 <= Node.val <= 100
  • Both list1 and list2 are sorted in non-decreasing order.

First Solution

💡 題目上方的註解是在提示你所使用的程式語言,它的Node結構長怎樣,
所以不用取消註解,不然反而會顯示 NoSuchMethodError
回到解題,這個題目我有點印象,是對LinkedList進行MergeSort。
不過有點久沒寫就忘記了,而且我也沒有用Java寫過。

我最初的想法是,用4個指標,L1、L2不斷向後搜尋,當作陣列搜尋進度。
H1、H2則當作合併時的參考點。
如果L1的值大於L2,L2就繼續往後找。
如果L1的值小於或等於L2,就要開始進行合併,合併的步驟如下:
  1. 將L1指標向右移,此時L1表示下一個要搜尋的值,H1表示當下要進行合併的值
  2. H1指向L2,進行合併
  3. H2指向H1,表示陣列的頭
  4. H1指標移向L1,做為下一次合併的參考點。
不過這遇到了一些問題,
包含H2參考點仍然會越來越後面,導致最後無法回到陣列的頭,
以及Java沒有指標,而是用Node物件去進行操作的方式讓我有點混亂,
所以很可惜,第一次沒有解出來。
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {

// empty condition.
if(list1 == null && list2 == null)
return list1;
if(list1 == null)
return list2;
if(list2 == null)
return list1;

// Deal with link problem.

ListNode headL1 = new ListNode();
headL1 = list1;
ListNode headL2 = new ListNode();
headL2 = list2;

while(list1 != null || list2 != null){
if(list1.val <= list2.val){
list1 = list1.next;
headL1.next = list2;
headL2 = headL1;
headL1 = list1;
}
else if(list1.val > list2.val){
list2 = list2.next;
}
}
return headL2;
}
}
⏰ Runtime: ?? ms (?? %)
📦 Memory: ?? MB (?? %)

Upgrade Solution

recursive.
💡 遞迴,神奇的遞迴,OMG。

其實不用特別處理陣列為空的狀況,
此範例是合併在list1,所以兩個都空,回傳哪一個都可以,
list1為空,回傳list2的值,
而無論是list2為空,還是要回傳整理好的陣列,
都是回傳list1。

這個遞迴的運作方式,畫成圖表是長這樣:
用遞迴的方式,讓函式本身從每一輪都挑出比較小的那個值,最後遞迴結束後再反向回傳,就能得到由小到大的回傳結果。

神技。Orz
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1!=null && list2!=null){
if(list1.val < list2.val){
list1.next = mergeTwoLists(list1.next,list2);
return list1;
}
else{
list2.next = mergeTwoLists(list1,list2.next);
return list2;
}
}
if(list1==null)
return list2;

return list1;
}
}
⏰ Runtime: 0 ms (100 %)
📦 Memory: 41.8 MB (86.38 %)

Upgrade Solution 2

4 Nodes, like first solution.
💡 這個做法就解決了前面「陣列的頭跑掉」的問題,
而它不是合併在list1或list2,
而是用了一個新陣列prehead依大小吞食兩個陣列。
  • 這邊用prehead作為固定不動,永遠指在最前面的標頭,用cur作為向後追蹤的參考點。
  • 吞食的方式是一個一個吃,只要list1的值比較小,就將list1放進陣列,list2的值比較小,就將list2放進陣列,看是放進哪一個陣列的值,該陣列的指標就向後移一格,同時cur每吃掉一個值就往後移一格。
  • 當一個陣列空了以後,檢查兩個陣列還有沒有值,有就接在cur的後面。
  • 最後回傳固定在陣列頭的prehead。
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode cur = prehead;

while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
cur.next = l1;
l1 = l1.next;
} else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}

cur.next = l1 == null ? l2 : l1;
return prehead.next;
}
}
⏰ Runtime: 0 ms (100 %)
📦 Memory: 42.6 MB (20.37 %)
為什麼會看到廣告
avatar-img
6會員
36內容數
以英文和日文歌的翻譯為主,並從「歌曲裡的故事」這個角度去翻譯。畢竟自己只有中文算好而已 :D
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Steven SHIH的沙龍 的其他內容
Valid Parentheses : 確認input的括號是否符合成雙成對的規則,符合回傳true,否則回傳false.
Longest Common Prefix : 回傳陣列中所有字串的最長共同前序(LCP),也就是從最前面開始依序算起,所有字串都擁有的字元。
Roman to Integer : 將羅馬數字轉換成阿拉伯數字。
Palindrome Number : 判斷x是否為迴文 ( 左到右,右到左,內容皆相同 ) ,若符合回傳true,不符合則回傳false。
Two Sum : 在Array中找出相加後與Target相同的兩個數字,並將他們的index存在新的陣列。
Valid Parentheses : 確認input的括號是否符合成雙成對的規則,符合回傳true,否則回傳false.
Longest Common Prefix : 回傳陣列中所有字串的最長共同前序(LCP),也就是從最前面開始依序算起,所有字串都擁有的字元。
Roman to Integer : 將羅馬數字轉換成阿拉伯數字。
Palindrome Number : 判斷x是否為迴文 ( 左到右,右到左,內容皆相同 ) ,若符合回傳true,不符合則回傳false。
Two Sum : 在Array中找出相加後與Target相同的兩個數字,並將他們的index存在新的陣列。
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
題目敘述 Merge Nodes in Between Zeros 給定一個鏈結串列,合併非零區間的節點(以加總的方式合併),輸出合併後的鏈結串列。
Thumbnail
題目敘述 題目給定一個鏈結串列中的節點Node,要求我們從鏈結串列中刪除該節點。 題目保證該節點不是tail node。 題目要求我們in-place原位操作。 原本的英文題目敘述 測試範例 Example 1: Input: head = [4,5,1,9], node = 5
Thumbnail
題目敘述 輸入給定一個鏈結串列的head node。 要求我們進行化簡,只要某個節點的右手邊存在比較大的節點,就刪除掉。 例如 5->2->13->3 5的右手邊有13,所以5刪除掉。 2的右手邊有13,所以2刪除掉。 13的右手邊沒有更大的節點,所以13留著。 3的右手邊沒有更大
Thumbnail
題目敘述 題目會給定一個鏈結串列 Linked List的頭部結點,要求我們根據索引的奇偶數重新排列。奇數索引的在前,偶數索引的在後。數的時候,從Head節點的索引=1開始數。 例如: 1 -> 2 -> 3 -> 4 -> 5 重新排列為 1 -> 3 -> 5 -> 2 -> 4
Thumbnail
題目敘述 題目會給我們一個鏈結串列的頭部結點Head node,要求我們計算鏈結串列中的Twin sum最大值是多少? 註: Twin Sum的定義就是頭尾結點相對位置相同的,互相配對加總在一起的值。 例如 給定串列= 1 -> 3 -> 2 -> 5 -> 100 -> 8 1, 8 一組
Thumbnail
題目敘述 題目會給定我們一條鏈結串列Linked list的起始節點,要求我們刪除Linked List正中央的節點。 註: 正中央的節點,題目定義為索引為floor( 串列長度 / 2 ) 的節點,索引從零(Head Node)出發開始數。 例如 1 -> 2 -> 3 -> 4 鏈結
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
Thumbnail
這題也是滿經典的DP動態規劃教學案例和題目,就順便複習一下吧。 題目敘述 題目會給我們兩個字串text1, text2。 要求我們找出兩個字串的最長共同子序列,並且返回最長共同子序列的長度。 如果彼此沒有共同子序列,則返回0。 題目的原文敘述 測試範例 Example 1: In
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
題目敘述 Merge Nodes in Between Zeros 給定一個鏈結串列,合併非零區間的節點(以加總的方式合併),輸出合併後的鏈結串列。
Thumbnail
題目敘述 題目給定一個鏈結串列中的節點Node,要求我們從鏈結串列中刪除該節點。 題目保證該節點不是tail node。 題目要求我們in-place原位操作。 原本的英文題目敘述 測試範例 Example 1: Input: head = [4,5,1,9], node = 5
Thumbnail
題目敘述 輸入給定一個鏈結串列的head node。 要求我們進行化簡,只要某個節點的右手邊存在比較大的節點,就刪除掉。 例如 5->2->13->3 5的右手邊有13,所以5刪除掉。 2的右手邊有13,所以2刪除掉。 13的右手邊沒有更大的節點,所以13留著。 3的右手邊沒有更大
Thumbnail
題目敘述 題目會給定一個鏈結串列 Linked List的頭部結點,要求我們根據索引的奇偶數重新排列。奇數索引的在前,偶數索引的在後。數的時候,從Head節點的索引=1開始數。 例如: 1 -> 2 -> 3 -> 4 -> 5 重新排列為 1 -> 3 -> 5 -> 2 -> 4
Thumbnail
題目敘述 題目會給我們一個鏈結串列的頭部結點Head node,要求我們計算鏈結串列中的Twin sum最大值是多少? 註: Twin Sum的定義就是頭尾結點相對位置相同的,互相配對加總在一起的值。 例如 給定串列= 1 -> 3 -> 2 -> 5 -> 100 -> 8 1, 8 一組
Thumbnail
題目敘述 題目會給定我們一條鏈結串列Linked list的起始節點,要求我們刪除Linked List正中央的節點。 註: 正中央的節點,題目定義為索引為floor( 串列長度 / 2 ) 的節點,索引從零(Head Node)出發開始數。 例如 1 -> 2 -> 3 -> 4 鏈結
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
Thumbnail
這題也是滿經典的DP動態規劃教學案例和題目,就順便複習一下吧。 題目敘述 題目會給我們兩個字串text1, text2。 要求我們找出兩個字串的最長共同子序列,並且返回最長共同子序列的長度。 如果彼此沒有共同子序列,則返回0。 題目的原文敘述 測試範例 Example 1: In