iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
自我挑戰組

Leetcode 小白練功坊系列 第 23

[DAY23] 2. Add Two Numbers

  • 分享至 

  • xImage
  •  

題目連結(https://leetcode.com/problems/add-two-numbers/description/)

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

一直不想面對 Linked list,但還是要練,所以拿經典題來寫~

1. Repeat(題目重複確認)

  • 輸入:兩個非空的 Linked lists 存非負整數,位數是相反方向
    • 每個節點都表示一個位數,將兩數相加
  • 輸出:回傳總和(以 Linked lists 表示)
  • 前提:
    • The number of nodes in each linked list is in the range [1, 100]. 不會有空的 Linked list
    • 0 <= Node.val <= 9
    • It is guaranteed that the list represents a number that does not have leading zeros.

2. Examples(舉例確認理解)

l1 = 2→4→3

l2 = 5→6→4

從尾串到頭(個位),相加然後再給出新的 Linked list

Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.


3. Approach(解題思路)

方法 :

  • 相加的思考邏輯
    • while 條件l1 || l2 || carry(三者任一存在就繼續)
    • 進位計算carry = sum / 10
    • 當前位digit = sum % 10
  • 時間複雜度:O(max(m, n))
  • 空間複雜度:O(max(m, n))其中 m、n 是兩個鏈表的長度。
// 創建節點
ListNode* node = new ListNode(5);

// 訪問值
int value = node->val;

// 訪問下一個節點
ListNode* nextNode = node->next;

// 遍歷鏈表
while (node != nullptr) {
    cout << node->val;
    node = node->next;  // 移動到下一個
}

4. Code(C++)

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* dummy = new ListNode(0);
        ListNode* current = dummy; // current 指向 dummy
        int carry = 0; //record是否要進位
        // 只要還有節點或還有進位,就繼續
        while(l1 || l2 || carry){
            int sum = carry;
            if(l1){
                sum += l1 ->val;
                l1 = l1 -> next;
            }
            if(l2){
                sum += l2 ->val;
                l2 = l2 -> next;
            }
                
            carry = sum/10; //多出來的十位數字表示進位
            current -> next = new ListNode(sum%10);//餘數當節點值
            current = current -> next;
        }
        return dummy->next;
    }
};

5. Test 範例

範例: [2,4,3] + [5,6,4] = [7,0,8]

步驟 1: 2 + 5 + 0(進位) = 7
  l1: 2 -> 4 -> 3
  l2: 5 -> 6 -> 4
  結果: 7
  carry: 0

步驟 2: 4 + 6 + 0(進位) = 10
  l1: 4 -> 3
  l2: 6 -> 4
  結果: 7 -> 0
  carry: 1

步驟 3: 3 + 4 + 1(進位) = 8
  l1: 3
  l2: 4
  結果: 7 -> 0 -> 8
  carry: 0

6. 相關題目與延伸概念

**Multiply Strings Medium**

**Add Binary Easy**

**Sum of Two Integers Medium**

7. 補充:語法&注意事項

// 節點定義
struct ListNode {
    int val;           // 節點的值
    ListNode *next;    // 指向下一個節點的指針
    
    // 函數
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};
初始化:
dummy & current
    ↓
  ┌───┬────┐
  │ 0 │null│
  └───┴────┘

加入第一個節點 (7):
dummy        current
  ↓             ↓
┌───┬────┐   ┌───┬────┐
│ 0 │ ●--├──>│ 7 │null│
└───┴────┘   └───┴────┘

完整鏈表:
dummy              第1個         第2個         第3個
  ↓                 ↓             ↓             ↓
┌───┬────┐       ┌───┬────┐   ┌───┬────┐   ┌───┬────┐
│ 0 │ ●--├──────>│ 7 │ ●--├──>│ 0 │ ●--├──>│ 8 │null│
└───┴────┘       └───┴────┘   └───┴────┘   └───┴────┘

return dummy->next 返回這個指針 ↓
                              ┌───┬────┐   ┌───┬────┐   ┌───┬────┐
                              │ 7 │ ●--├──>│ 0 │ ●--├──>│ 8 │null│
                              └───┴────┘   └───┴────┘   └───┴────┘

1. dummy 是虛擬頭節點

  • 它的值(0)不重要,只是占位
  • 作用:讓我們不用特殊處理第一個真實節點
  • 最後會跳過它:return dummy->next

2. 名詞解釋

dummy虛擬占位,最後丟棄

current = dummy表示指針指向位置,不是複製

new ListNode(值) 建立節點,括號內是 val

return dummy->next返回頭部,即可連續返回整個鏈表

  • 只要有第一個節點的地址 ->next 訪問所有後續節點
  • 就像拿著一串珠子的第一顆,整串就都有了!

3. 空指標語法

if (l1)if (l1 != nullptr) 是相同的,都代表說 l1 還有值,非空

ps. 部分內容經 AI 協助整理


上一篇
[DAY22] 11. Container With Most Water
下一篇
[DAY24] 24. Swap Nodes in Pairs
系列文
Leetcode 小白練功坊24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言