LeetCode 445 Add Two Numbers II


445-Add Two Numbers II

You are given two linked lists representing two non-negative numbers. The most significant digit comes first 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.

Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.

Example:

Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7

題解

比2-Add Two Numbers稍微麻煩一點。簡單的想法是反轉兩個鏈表,就變成了2-Add Two Numbers的問題,轉換有兩種方法,一種式直接在原來的鏈表上轉換,一種是利用棧來轉換。

利用棧

struct ListNode {
  int val;
  ListNode *next;
  ListNode(int x) : val(x), next(NULL) {}
};

ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
  if (l1 == NULL) return l2;
  if (l2 == NULL) return l1;
  stack<int> st1, st2;
  ListNode *head = NULL;
  ListNode *cur = NULL;
  int sum = 0;
  int carry = 0;
  while (l1 != NULL) {
    st1.push(l1->val);
    l1 = l1->next;
  }
  while (l2 != NULL) {
    st2.push(l2->val);
    l2 = l2->next;
  }
  //用兩個while邏輯上差了些,但是減少了判斷次數
  while (!st1.empty()) {
    if (!st2.empty()) {
      sum = st1.top() + st2.top() + carry;
      carry = sum > 9 ? 1 : 0;
      cur = head;
      head = new ListNode(sum % 10);
      head->next = cur;
      st1.pop();
      st2.pop();
    } else {
      sum = st1.top() + carry;
      carry = sum > 9 ? 1 : 0;
      cur = head;
      head = new ListNode(sum % 10);
      head->next = cur;
      st1.pop();
    }
  }
  while (!st2.empty()) {
    sum = st2.top() + carry;
    carry = sum > 9 ? 1 : 0;
    cur = head;
    head = new ListNode(sum % 10);
    head->next = cur;
    st2.pop();
  }
  
  if (carry) {
    cur = head;
    head = new ListNode(1);
    head->next = cur;
  }
  return head;
}

直接反轉鏈表

有兩種辦法:

  1. 遍歷節點,依次把節點插到head之前,每次插入后需要維護好head指針。
  2. 用3個指針來實現,反轉next之后,3指針移動一個節點。

不需要反轉鏈表的方法

  1. 先遍歷兩個鏈表,計算兩個鏈表的長度
  2. 根據鏈表長度,對應節點相加
  3. 利用兩個指針實現進位。對於進位,當前位需要進位時,高1位如果不是就9,直接進1位就結束,如果是9,需要進位到依次的高1位不是9才停止,也就是只要知道需要進位的位前的第一個不為9的位,就知道了進位的范圍了。- piont1從頭開始遍歷
    • 如果point1->val< 9令piont2 = point1
    • 如果point1>9,對point2到point1的節點加1,模10
      如果head大於10需要先生成一個節點。point1->val< 9的判斷成功的次數有點多啊,不知道有沒有優化的方法。
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
  if (l1 == NULL) return l2;
  if (l2 == NULL) return l1;

  int len1 = 0;
  int len2 = 0;
  for (ListNode *p = l1; p != NULL; p = p->next) ++len1;
  for (ListNode *p = l2; p != NULL; p = p->next) ++len2;
  if (len1 < len2) {
    int tmp = len1;
    len1 = len2;
    len2 = tmp;
    ListNode *p = l1;
    l1 = l2;
    l2 = p;
  }
  ListNode *head = new ListNode(0);
  ListNode *cur = head;
  for (int i = len1 - len2; i != 0; --i) {
    cur->next = new ListNode(l1->val);
    cur = cur->next;
    l1 = l1->next;
  }
  while (l1) {
    cur->next = new ListNode(l1->val + l2->val);
    cur = cur->next;
    l1 = l1->next;
    l2 = l2->next;
  }

  //有可能最高進位,我習慣head是空,為了方便,如果進位就直接進到head
  //返回時通過head->val是0或1確定返回head還是head->next
  ListNode *bound = head;
  cur = head->next;
  while (cur) {
    if (cur->val < 9)
      bound = cur;
    else if (cur->val > 9) {
      while (bound != cur) {
        bound->val = (bound->val + 1) % 10;
        bound = bound->next;
      }
      cur->val -= 10;
    }
    cur = cur->next;
  }

  if (head->val == 1)
    return head;
  else
    return head->next;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM