0

I'm trying a standard interview question, which is to add two digits in the form of linkedlists and return the added answer. Here is the question:

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

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

342 + 465 = 807 Make sure there are no trailing zeros in the output list So, 7 -> 0 -> 8 -> 0 is not a valid response even though

the value is still 807.

Now, the code I am writing takes in two arguments in the form of ListNode datatypes which is the starting node of the LinkedLists. What I am not understanding is

  1. How do I maintain the head node of the list to reference later?
  2. How does call by value and call by reference work in Java? I've dealt with pointers and call by reference in C++ but I've been trying stuff in Java now and it's pretty different.

    class ListNode {
        public int val;
        public ListNode next;
        ListNode(int x) {
            val = x;
            next = null;
        }
    }
    
    
    public class Solution {
    
        public ListNode reverse(ListNode head) {
            ListNode curr = head;
            ListNode next = null;
            ListNode prev = null;
            while (curr != null) {
                next = curr.next;
                curr.next = prev;
                prev = curr;
                curr = next;
            }
            head = prev;
            return head;
        }
    
    
        public ListNode addTwoNumbers(ListNode a, ListNode b) {
            ListNode node = null;
            ListNode head = null;
            boolean carry = false;
            while (a != null || b != null) {
                int f = 0, s = 0;
                if (carry) {
                    f++;
                }
                carry = false;
                if (a != null) {
                    f += a.val;
                    a = a.next;
                }
                if (b != null) {
                    s = b.val;
                    b = b.next;
                }
                if (f + s > 9) {
                    carry = true;
                }
                int curr = (f + s) % 10;
                node = new ListNode(curr);
                if (head == null) {
                    head = node;
                }
                node = node.next; //warning that 'value of node assigned is never used'
            }
            if (carry) {
                node = new ListNode(1);
            }
            printList(head);
            return node;
        }
    }
    
tsaebeht
  • 1,570
  • 5
  • 18
  • 32
  • "How does call by value and call by reference work in Java" Java is [call-by-value](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value), always. But what is meant by "value" in this context is confusing: the value of the variable which is passed, which may be a reference. So whilst the referenced object isn't passed by value, the variable referring to that object is; this means that you can't do things like swapping values in a separate method, like you can in C++. – Andy Turner Sep 30 '16 at 10:54
  • @AndyTurner What would be the best way to deal with LinkedList questions such as this in Java? Maintaining the head and other values in a pain because in Java, if I simply do `head = node` then the value of head changes according to node and I can't retrieve the head value in the end. How to avoid this? – tsaebeht Sep 30 '16 at 11:00

2 Answers2

1

node plays an ambiguous role.

        node = new ListNode(curr);
        node = node.next; // assigns null

Rename node into previous and do:

        int curr = (f + s) % 10;
        ListNode newNode = new ListNode(curr);
        if (head == null) { // Or `previous == null`
            head = newNode;
        } else {
            previous.next = newNode;
        }
        previous = newNode;

    ...
    return head;

The technique to handle head is to make it a private field of a container class LinkedList.

As in java the parameter passing is call-by-value: f(a) never changes the variable a: the slot where the object pointer / value is stored. Instead to object pointer / value is pushed on the stack. (The object value may have its fields changed.)

So a recursive insert might look like head = insert(head, ...).

In C on can use aliasing, not only for parameter passing:

ListNode* head = NULL;
ListNode** node = &head;
shile (...) {
    ...
    *node = newNode;
    node = &(newNode->next);
}
Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • `The technique to handle head is to make it a private field of a container class LinkedList` This is exactly what thought. The previous method seems a good workaround this issue, Thanks – tsaebeht Sep 30 '16 at 11:26
  • Your answer fails me. If I print the values of `head` and previous at every stage, I get the same answer. Have a look at the code here:http://ideone.com/N7dvLX – tsaebeht Sep 30 '16 at 11:36
  • Please edit your answer. It would be ` int curr = (f + s) % 10; ListNode newNode = new ListNode(curr); if (previous == null) { previous = newNode; head = newNode; } else { previous.next = newNode; previous = previous.next; }` – tsaebeht Sep 30 '16 at 11:41
  • I saw `previous = previous.next` which would be assigning null to previous but at the end of the loop one sets previous to newNode. Then all should work. – Joop Eggen Sep 30 '16 at 12:35
  • At the start when previous is null and you're assigning it `newNode`, you needn't do `previous = previous.next`. You're already there. You only need to do that in iterations further on. Here is the correct code which got accepted:http://ideone.com/f3yhBR – tsaebeht Sep 30 '16 at 12:58
0

Why so complicated?

public class Solution {

    public ListNode addTwoNumbers(ListNode a, ListNode b) {
        int firstNumber = nodeToNumber(a);
        int secondNumber = nodeToNumber(b);
        return numberToNode(firstNumber + secondNumber);
    }

    public int nodeToNumber(ListNode node) {
        if (node.next != null) return node.value + 10 * nodeToNumber(node.next);
        return node.value;
    }

    public ListNode numberToNode(int number) {
        ListNode result = new ListNode(number % 10);
        if (number > 10) result.next = numberToNode(number / 10);
        return result;
    }
}
Mark
  • 1,498
  • 1
  • 9
  • 13