英文:
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.
中文:
給定兩個代表非負整數的非空連結串列。數字以相反的順序存儲,每個節點包含一個數字。將這兩個數相加並將和作為一個連結串列返回。
你可以假設這兩個數字不包含任何前導零,除非數字本身是0。
這是一個常見的鏈表問題,需要模擬加法的過程。我們從鏈表的頭部開始,將相應位置的數字相加,並記錄進位。最終,我們得到了一個新的鏈表,代表兩數之和。
1Input:
2 L1: 2 -> 4 -> 3
3 L2: 5 -> 6 -> 4
4Output:
5 Result: 7 -> 0 -> 8
1namespace UnitTestDay2_AddTwoNumbers
2{
3 public class Solution
4 {
5 public class ListNode
6 {
7 public int val;
8 public ListNode next;
9 public ListNode( int val = 0, ListNode next = null )
10 {
11 this.val = val;
12 this.next = next;
13 }
14 }
15
16 public ListNode AddTwoNumbers( ListNode l1, ListNode l2 )
17 {
18 ListNode dummyHead = new ListNode( 0 );
19 ListNode current = dummyHead;
20 int carry = 0;
21
22 while (l1 != null || l2 != null)
23 {
24 int x = l1?.val ?? 0;
25 int y = l2?.val ?? 0;
26 int sum = carry + x + y;
27
28 carry = sum / 10;
29 current.next = new ListNode( sum % 10 );
30
31 l1 = l1?.next;
32 l2 = l2?.next;
33 current = current.next;
34 }
35
36 if (carry > 0)
37 {
38 current.next = new ListNode( carry );
39 }
40
41 return dummyHead.next;
42 }
43 }
44}
這是 C# 的解法,我們使用了 ListNode 類別來表示連結串列中的節點。主要邏輯在 AddTwoNumbers
方法中。
current
指針來表示當前節點,初始指向 dummyHead。carry
變數用來處理進位,初始值為 0。l1
和 l2
,並同時進行加法操作和進位處理。l1
和 l2
的值(如果存在),加上上一輪的進位值 carry
,計算總和 sum
和進位。sum % 10
放入結果串列的當前節點中,同時將進位 carry
更新為 sum / 10
。l1
、l2
和 current
指針以繼續下一輪計算。 1namespace UnitTestDay2_AddTwoNumbers.Tests
2{
3 [TestClass()]
4 public class SolutionTests
5 {
6 private Solution UT = new Solution();
7
8 [TestMethod()]
9 public void Test1()
10 {
11 // Arrange
12 ListNode l1 = CreateLinkedList( 2, 4, 3 );
13 ListNode l2 = CreateLinkedList( 5, 6, 4 );
14 ListNode expected = CreateLinkedList( 7, 0, 8 );
15
16 // Act
17 ListNode result = UT.AddTwoNumbers( l1, l2 );
18
19 // Assert
20 Assert.IsTrue( CompareLinkedLists( expected, result ) );
21 }
22
23 [TestMethod()]
24 public void Test2()
25 {
26 // Arrange
27 ListNode l1 = CreateLinkedList( 0 );
28 ListNode l2 = CreateLinkedList( 0 );
29 ListNode expected = CreateLinkedList( 0 );
30
31 // Act
32 ListNode result = UT.AddTwoNumbers( l1, l2 );
33
34 // Assert
35 Assert.IsTrue( CompareLinkedLists( expected, result ) );
36 }
37
38 [TestMethod()]
39 public void Test3()
40 {
41 // Arrange
42 ListNode l1 = CreateLinkedList( 9, 9, 9, 9, 9, 9, 9 );
43 ListNode l2 = CreateLinkedList( 9, 9, 9, 9 );
44 ListNode expected = CreateLinkedList( 8, 9, 9, 9, 0, 0, 0, 1 );
45
46 // Act
47 ListNode result = UT.AddTwoNumbers( l1, l2 );
48
49 // Assert
50 Assert.IsTrue( CompareLinkedLists( expected, result ) );
51 }
52
53 // Helper method to create a linked list from an array of values
54 private ListNode CreateLinkedList( params int[] values )
55 {
56 if (values == null || values.Length == 0)
57 return null;
58
59 ListNode head = new ListNode( values[0] );
60 ListNode current = head;
61
62 for (int i = 1; i < values.Length; i++)
63 {
64 current.next = new ListNode( values[i] );
65 current = current.next;
66 }
67
68 return head;
69 }
70
71 // Helper function to compare two linked lists
72 private bool CompareLinkedLists( ListNode list1, ListNode list2 )
73 {
74 while (list1 != null && list2 != null)
75 {
76 if (list1.val != list2.val)
77 {
78 return false;
79 }
80 list1 = list1.next;
81 list2 = list2.next;
82 }
83
84 // Check if both lists are of equal length
85 return list1 == null && list2 == null;
86 }
87 }
88}
1class ListNode:
2 def __init__(self, val=0, next=None):
3 self.val = val
4 self.next = next
5
6class Solution:
7 def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
8 dummy_head = ListNode(0)
9 current = dummy_head
10 carry = 0
11
12 while l1 or l2:
13 x = l1.val if l1 else 0
14 y = l2.val if l2 else 0
15 _sum = carry + x + y
16
17 carry = _sum // 10
18 current.next = ListNode(_sum % 10)
19
20 if l1:
21 l1 = l1.next
22 if l2:
23 l2 = l2.next
24 current = current.next
25
26 if carry > 0:
27 current.next = ListNode(carry)
28
29 return dummy_head.next
這是 Python 的解法,和 C# 解法類似。我們使用了 ListNode 類別來表示連結串列中的節點,並實現了 addTwoNumbers
方法來執行加法操作和進位處理。
current
指針來表示當前節點,初始指向 dummy_head。carry
變數用來處理進位,初始值為 0。l1
和 l2
,同時進行加法操作和進位處理。l1
和 l2
的值(如果存在),加上上一輪的進位值 carry
,計算總和 _sum
和進位。_sum % 10
放入結果串列的當前節點中,同時將進位 carry
更新為 _sum // 10
。l1
、l2
和 current
指針以繼續下一輪計算。 1namespace UnitTestDay2_AddTwoNumbers.Tests
2{
3 [TestClass()]
4 public class SolutionTests
5 {
6 private Solution UT = new Solution();
7
8 [TestMethod()]
9 public void Test1()
10 {
11 // Arrange
12 ListNode l1 = CreateLinkedList( 2, 4, 3 );
13 ListNode l2 = CreateLinkedList( 5, 6, 4 );
14 ListNode expected = CreateLinkedList( 7, 0, 8 );
15
16 // Act
17 ListNode result = UT.AddTwoNumbers( l1, l2 );
18
19 // Assert
20 Assert.IsTrue( CompareLinkedLists( expected, result ) );
21 }
22
23 [TestMethod()]
24 public void Test2()
25 {
26 // Arrange
27 ListNode l1 = CreateLinkedList( 0 );
28 ListNode l2 = CreateLinkedList( 0 );
29 ListNode expected = CreateLinkedList( 0 );
30
31 // Act
32 ListNode result = UT.AddTwoNumbers( l1, l2 );
33
34 // Assert
35 Assert.IsTrue( CompareLinkedLists( expected, result ) );
36 }
37
38 [TestMethod()]
39 public void Test3()
40 {
41 // Arrange
42 ListNode l1 = CreateLinkedList( 9, 9, 9, 9, 9, 9, 9 );
43 ListNode l2 = CreateLinkedList( 9, 9, 9, 9 );
44 ListNode expected = CreateLinkedList( 8, 9, 9, 9, 0, 0, 0, 1 );
45
46 // Act
47 ListNode result = UT.AddTwoNumbers( l1, l2 );
48
49 // Assert
50 Assert.IsTrue( CompareLinkedLists( expected, result ) );
51 }
52
53 // Helper method to create a linked list from an array of values
54 private ListNode CreateLinkedList( params int[] values )
55 {
56 if (values == null || values.Length == 0)
57 return null;
58
59 ListNode head = new ListNode( values[0] );
60 ListNode current = head;
61
62 for (int i = 1; i < values.Length; i++)
63 {
64 current.next = new ListNode( values[i] );
65 current = current.next;
66 }
67
68 return head;
69 }
70
71 // Helper function to compare two linked lists
72 private bool CompareLinkedLists( ListNode list1, ListNode list2 )
73 {
74 while (list1 != null && list2 != null)
75 {
76 if (list1.val != list2.val)
77 {
78 return false;
79 }
80 list1 = list1.next;
81 list2 = list2.next;
82 }
83
84 // Check if both lists are of equal length
85 return list1 == null && list2 == null;
86 }
87 }
88}
這個題目的目的是將兩個以連結串列表示的數相加,並返回結果。總結一下解題技巧,解決這個問題的關鍵在於有效處理進位,並且在兩個連結串列不等長的情況下進行迭代計算,模擬加法的過程。時間複雜度為O(max(N, M)),其中N和M分別是兩個鏈表的長度,空間複雜度為O(max(N, M)),主要是結果鏈表的空間。