BAT面試演算法進階(1)--兩數之和
阿新 • • 發佈:2018-12-18
一.演算法題
題目
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 contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
- Example
輸入: (2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出: 7 -> 0 -> 8
原因: 342 + 465 = 807.
複製程式碼
二. 解決方案:
題目大意:給定2個非空連結串列來表示2個非負整數.位數按照逆序方式儲存,它們的每個節點只儲存單個數字,將兩數相加返回一個新的連結串列.你可以假設除了數字0之外,這2個數字都不會以零開頭.
2.1 思路
我們使用變數來跟蹤進位,並從包含最低有效位的表頭開始模擬逐位相加的過程.
2.2 演算法
就如同小學數學計算2個數相加一般,我們首先從低位有效位計算,也就是L1
L2
的表頭第一個位置開始相加.我們進行的十進位制相加,所以當計算的結果大於9時,就會造成"溢位"的現象.例如5+7=12
.此時,我們就會把當前為的值設定為2,但是溢位的位需要進位.那麼則用carry
儲存,carry = 1
.帶入到下一次迭代計算中.進位的carry
必定是0或者1.2個數累加,需要考慮進位問題.則採用一個變數來儲存進位值.
2.3 虛擬碼
- 將當前節點初始化為返回列表的啞節點;
- 將進位carry設定為0;
- 將p,q分別指向為列表L1,L2的頭部.
- 遍歷列表L1,L2直到他們的尾端.
- 將x設為節點的p的值.如果P已經到達L1的末尾,則將其值設定為0;
- 將y設定為節點q的值,如果q已經到達L2的末尾,則將其值設定為0;
- 求和 sum = x+y+carry;
- 更新進位 carry = sum/10;
- 建立一個新的節點,將其設定為下一個節點.並將當前節點移動到下一節點
- 同時,將p,q移動到下一個節點位置.
- 檢查carry 是否等於1,如果等於1則往列表中追加數字1到新節點中.
- 返回啞節點的下一個節點.
2.4 複雜度分析
- 時間複雜度:
O(max(m,n))
,假設m,n分別表示L1,l2長度.上面的演算法最多重複max(m,n)
次 - 空間複雜度:
O(max(m,n))
, 新列表的長度最多max(m,n)+1
2.5 參考程式碼
#include <stdio>
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode* addTwoNumbers(struct ListNode * l1, struct ListNode * l2) {
struct ListNode *dummyHead = (struct ListNode *)malloc(sizeof(struct ListNode));
struct ListNode *p = l1, *q = l2, *curr = dummyHead;
int carry = 0;
while (p != NULL || q != NULL) {
int x = (p != NULL) ? p->val : 0;
int y = (q != NULL) ? q->val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr->next = (struct ListNode *)malloc(sizeof(struct ListNode));
curr->val = sum;
curr = curr->next;
if (p != NULL) p = p->next;
if (q != NULL) q = q->next;
}
if (carry > 0) {
curr->next = (struct ListNode *)malloc(sizeof(struct ListNode));
}
return curr;
}
複製程式碼
感謝大家觀看這一篇文章,給大家獻上了iOS開發的188道面試題哦! 加小編的群就可以直接獲取哦!551346706