leetcode445. Add Two Numbers II

Subject requirements

You are given two non-empty linked 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.

Example:

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

Two integers in the form of linked list are accumulated.

Idea 1: linked list transposition

The biggest difference between linked list form and non linked list form is that we cannot access the elements corresponding to the subscript according to the subscript. If we want to sum each position from back to front, we must access the value of the corresponding subscript from front to back every time. So here we can add up by first transposing the linked list and then summing each bit from left to right.

The transposition method of the linked list is as follows:

Suppose the list is 1 - > 2 - > 3
 Set a pseudo header for it: dummy - > 1 - > 2 - > 3, and record that the current element to be exchanged is cur
 Then each transpose is as follows:
dummy->1(cur)->2->3
dummy->2->1(cur)->3
dummy->3->2->1(cur)

The code is as follows:

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode rl1 = reverse(l1);
        ListNode rl2 = reverse(l2);
        ListNode result = new ListNode(0);
        int carry = 0;
        while(rl1 != null || rl2 != null || carry != 0) {
            int add = (rl1 == null ? 0 : rl1.val)
                    + (rl2 == null ? 0 : rl2.val)
                    + carry;
            carry = add / 10;
            ListNode tmp = new ListNode(add % 10);
            tmp.next = result.next;
            result.next = tmp;
            rl1 = rl1==null? rl1 : rl1.next;
            rl2 = rl2==null? rl2 : rl2.next;
        }
        return result.next;
    }
    
    public ListNode reverse(ListNode l) {
        ListNode dummy = new ListNode(0);
        dummy.next = l;
        ListNode cur = l;
        while(cur!= null && cur.next != null) {
            ListNode next = cur.next;
            cur.next = next.next;
            next.next = dummy.next;
            dummy.next = next;
        }
        return dummy.next;
    }

Idea 2: stack

If you don't want to change the structure of the list, how can you read the elements in the list in reverse order? At this time, you can quickly associate the stack structure. Through the stack, the first in and last out can be realized, that is, the transposition of the read order. The code is as follows:

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<Integer> s1 = new Stack<Integer>();
        Stack<Integer> s2 = new Stack<Integer>();
        while(l1 != null) {
            s1.push(l1.val);
            l1 = l1.next;
        };
        while(l2 != null) {
            s2.push(l2.val);
            l2 = l2.next;
        }
        
        int carry = 0;
        ListNode result = new ListNode(0);
        while(!s1.isEmpty() || !s2.isEmpty() || carry != 0) {
            int add = (s1.isEmpty() ? 0 : s1.pop())
                    + (s2.isEmpty() ? 0 : s2.pop())
                    + carry;
            carry = add / 10;
            ListNode tmp = new ListNode(add % 10);
            tmp.next = result.next;
            result.next = tmp;
        }
        return result.next;
    }

Tags: Java

Posted on Fri, 08 Nov 2019 12:46:27 -0500 by dfowler