LeetCode Algorithms 2. Add Two Numbers Solutions

Title:

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.

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

The meaning of the title is very clear. In translation, a non-negative integer is stored in a reverse one-way linked list, and then their addition is realized to obtain a reverse one-way linked list representation.

At the same time, the list node ListNode code is given.

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {};
};
  • According to the meaning of the title, the head node represents a bit, next points to 10 bits, then 100 bits, and so on. So when adding, align the two linked lists according to the head node and add them in turn.

  • When adding, we should pay attention to carry problem. Set a variable to represent carry, initialize it to 0, set carry to 1, and set no carry to 0. Then add this variable every time adding.

  • Another thing to note is that the number of digits of two numbers can be different, so we should pay attention to judging whether the two lists are empty during the cycle. In addition, because of the carry reason, the carry judgment is put into the cycle judgment condition (both lists are empty and no carry will exit the cycle), which can eliminate the judgment of the highest carry after the cycle ends.

Because the list problem involves pointers, it's still difficult to make purely hand-typed words, so I've been playing tricks on vs for a long time before running through the code. Here's the code I first submitted.

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *head, *current, *ln1, *ln2;
        vector<ListNode*> node;
        ln1 = l1;
        ln2 = l2;
        int increase = 0;
        while (ln1 != NULL || ln2 != NULL) {
            int sum = (ln1 != NULL ? ln1->val : 0) + (ln2 != NULL ? ln2->val : 0) + increase;
            current = new ListNode(sum < 10 ? sum : sum - 10);
            node.push_back(current);
            increase = sum < 10 ? 0 : 1;//carry
            ln1 = ln1 != NULL ? ln1->next : NULL;
            ln2 = ln2 != NULL ? ln2->next : NULL;
        }
        if (increase) {
            node.push_back(new ListNode(1));
        }
        head = node[0];
        current = head;
        if (node[node.size() - 1]->val == 0 && node.size() > 1) {
            node.pop_back();
        }
        if (node.size() > 1) {
            for (int i = 1; i < node.size(); i++) {
                current->next = node[i];
                //current->next = node[i + 1];
                current = current->next;
            }
        }
        return head;
    }
};

The code can be shortened by simplifying according to God's answer

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode head(0), *current = &head;
        int increase = 0;
        while (l1 || l2 || increase) {
            int sum = (l1 ? l1->val : 0) + (l2 ? l2->val : 0) + increase;
            current->next = new ListNode(sum % 10);
            current = current->next;
            increase = sum / 10;//carry
            l1 = l1 ? l1->next : NULL;
            l2 = l2 ? l2->next : NULL;
        }
        return head.next;
    }
};

In terms of efficiency, both codes are not high, both are more than 50 ms. Personally, there are too many judgment statements, which affect the speed.

Posted by schwa97 on Mon, 11 Feb 2019 02:39:17 -0800