1. 程式人生 > >BAT面試演算法進階(1)--兩數之和

BAT面試演算法進階(1)--兩數之和

一.演算法題

題目

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 思路

我們使用變數來跟蹤進位,並從包含最低有效位的表頭開始模擬逐位相加的過程.

Enter your image description here:

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

Enter your image description here:
Enter your image description here: