Add Two Numbers & Add Two Numbers ||

Insert at head (头插法)

Insert at tail (reverse a list) (尾插法) (Add Two Numbers ||)

C++ Member (dot & arrow) Operators

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode dummy(-1);
        //ListNode* prev = dummy;  // compile error
        ListNode* prev = &dummy;
        int carry = 0;

        //for (ListNode* pa = l1, ListNode* pb = l2; // compile error
        //for (ListNode* pa = l1, pb = l2;  // compile error
        for (ListNode* pa = l1, *pb = l2;
             pa != nullptr || pb != nullptr;
             pa = pa == nullptr ? nullptr : pa->next,
             pb = pb == nullptr ? nullptr : pb->next,
             prev = prev->next) {
             //prev = prev->next;) { // compile error

             int a = pa == nullptr ? 0 : pa->val;
             int b = pb == nullptr ? 0 : pb->val;
             int v = (a + b + carry) % 10;
             prev->next = new ListNode(v); \\ Insert at head

             carry = (a + b + carry) / 10;
        }

        if (carry != 0) {
            prev->next = new ListNode(carry);
        }
        //return dummy->next; // compile error!!!!! dummy is not a pointer, cannot be dereferenced
        return dummy.next;
    }
};

Add Two Numbers ||

You are given two non-emptylinked lists representing two non-negative integers. 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.

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

Method 1: reverse the List

相比于数字为倒序的链表相加问题(add two numbers),顺序的数字(单向)链表存在处理进位的问题,因为没有反向指针,所以后节点所得的进位,难以加到前一个节点上。 此外,与 add two numbers 问题一样,不能简单地将链表转为整形int或长整型long,因为很有可能超出范围,使用链表的好处正是在于可以几乎无限制地增加number的位数,如果有转换的过程,则很有可能丢失精度。+

因此,最简单的解决办法,就是将 add two numbers ii 问题,转化为 add two numbers 问题:先分别对每个number链表进行反转,然后进行相加,最后将所得链表再进行反转。

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* head1 = reverse(l1);
        ListNode* head2 = reverse(l2);
        ListNode* res = addTwoNumbers1(head1, head2);
        //ListNode* res1 = reverse(res);
        res = reverse(res);
        return res;

       // ListNode* h1 = head1;
       // while (h1) {
       //     cout << h1->val << ' ';
       //     h1 = h1->next;
       // }
       // cout << endl;
       // 
       // return head1;
    }

    ListNode* reverse(ListNode* head) {
        ListNode* prev = nullptr;

        // insert at tail
        while (head != nullptr) {
            ListNode* next = head->next;
            head->next = prev;
            prev = head;
            head = next;
        }
        return prev;
    }

    ListNode* addTwoNumbers1(ListNode* l1, ListNode* l2) {
        ListNode dummy(-1);
        ListNode* prev = &dummy;
        int carry = 0;

        for (ListNode* pa = l1, *pb = l2;
             pa != nullptr || pb != nullptr;
             pa = pa == nullptr ? nullptr : pa->next,
             pb = pb == nullptr ? nullptr : pb->next,
             prev = prev->next) {

             int a = pa == nullptr ? 0 : pa->val;
             int b = pb == nullptr ? 0 : pb->val;
             int v = (a + b + carry) % 10;
             prev->next = new ListNode(v);

             carry = (a + b + carry) / 10;
        }

        if (carry != 0) {
            prev->next = new ListNode(carry);
        }

        return dummy.next;
    }
};

Method 2: stack

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        stack<int> st1, st2;
        while (l1) {
            st1.push(l1->val);
            l1 = l1->next;
        }
        while (l2) {
            st2.push(l2->val);
            l2 = l2->next;
        }

        ListNode* prev = nullptr;
        int carry = 0;
        while (!st1.empty() || !st2.empty() || carry != 0) {
            int sum = 0;
            if (!st1.empty()) {
                sum = sum + st1.top();
                st1.pop();
            }
            if (!st2.empty()) {
                sum = sum + st2.top();
                st2.pop();
            }
            sum = sum + carry;
            // head Insert
            ListNode* head = new ListNode(sum % 10);
            head->next = prev;
            prev = head;

            carry = sum / 10;
        }

        //if (carry != 0) {
        //    ListNode* head = new ListNode(carry);
        //    head->next = prev;
        //    prev = head;
        //}

        return prev;

    }
};

Bug Version1

/**
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        stack<ListNode*> st1, st2;

        while (l1) {
            st1.push(l1);
            l1 = l1->next;
        }
        while (l2) {
            st1.push(l2);
            l2 = l2->next;
        }

        ListNode dummy(-1);
        ListNode* prev = &dummy;
        int carry = 0;
        while (!st1.empty() || !st2.empty()) {
            ListNode* pa = nullptr;
            ListNode* pb = nullptr;
            if (!st1.empty()) {
                pa = st1.top();
                st1.pop();
            }
            if (!st2.empty()) {
                pb = st2.top();
                st2.pop();
            }
            int a = pa == nullptr ? 0 :pa->val;
            int b = pb == nullptr ? 0 :pb->val;
            int sum = a + b + carry;
            int v = sum % 10;
            prev->next = new ListNode(v);
            prev = prev->next;
            carry = sum /10;
        }
        if (carry != 0) {
            prev->next = new ListNode(carry);
        }

        return dummy.next;
    }
};

results matching ""

    No results matching ""