HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Sum two linked lists

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
liststwolinkedsum

Problem

Write code to sum two numbers represented by a linked list. The digits
in this linked list are in reverse order. eg. (9->2->3) + (4->8->2) =
(3->1->6)

Any comments on my solution (especially on the testing part)?

public class ListNode {
    private int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }

    ListNode(ListNode other){
        val = other.val;
    }

    boolean hasNext() {
        if (this.next != null) {
            return true;
        } else {
            return false;
        }
    }

    public int getVal(){
        return this.val;
    }

    public void setVal(int v){
        this.val = v;
    }
}


public class SumTwo {
    /**
     * Iterative
     * @param l1
     * @param l2
     * @return
     */
    public ListNode addTwoNumbersV1(ListNode l1, ListNode l2) {
        if (l1 == null){
            l1 = new ListNode(0);
        }
        if (l2 == null){
            l2 = new ListNode(0);
        }

        int carry = 0;
        int total = l1.getVal() + l2.getVal() + carry;
        int num = total % 10;
        carry = total / 10;

        ListNode result = new ListNode(num);
        ListNode r = result;

        l1 = l1.next;
        l2 = l2.next;

        while (l1 != null || l2 != null) {
            if (l1 == null){
                l1 = new ListNode(0);
            }
            if (l2 == null){
                l2 = new ListNode(0);
            }

            total = l1.getVal() + l2.getVal() + carry;
            num = total % 10;
            carry = total / 10;

            r.next = new ListNode(num);
            r = r.next;
            l1 = l1.next;
            l2 = l2.next;
        }

        // if carry != 0 then add it
        if (carry == 1){
            r.next = new ListNode(1);
        }

        return result;
    }


```
public class SumTwoUtils {
public String printLinkedList(ListNode l){
StringBuffer s = new StringBuffer();
while (l != null){
s.append(l.ge

Solution

ListNode doesn't need to be mutable. You can remove the setter and set the value in the constructor. The result would be cleaner.

hasNext could return simply this.next != null; there is no need for the tedious if-else statement.

If one of the received ListNode is null, you can return the other node immediately. That will simplify quite a bit, and eliminate some duplicated logic you have going on there.

SumTwoUtils is a simple utility class with no data. You could make its only method static, and call it without an instance.

The tests... Are tedious and repetitive. You created a helper method to convert a linked list to string, but you could go further, and create a helper to do the reverse: linked list from integer. That would simplify the tests a lot, and make them a lot more readable too.

Suggested implementation

class ListNode {
    final int val;
    final ListNode next;

    public ListNode(int val) {
        this(val, null);
    }

    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    return addTwoNumbers(l1, l2, false);
}

private ListNode addTwoNumbers(ListNode l1, ListNode l2, boolean carry) {
    if (l1 == null) {
        return withCarryApplied(l2, carry);
    }
    if (l2 == null) {
        return withCarryApplied(l1, carry);
    }

    int sum = l1.val + l2.val + (carry ? 1 : 0);
    boolean nextCarry = sum >= 10;
    int val = nextCarry ? sum - 10 : sum;

    return new ListNode(val, addTwoNumbers(l1.next, l2.next, nextCarry));
}

private ListNode withCarryApplied(ListNode node, boolean carry) {
    if (!carry) {
        return node;
    }
    return addTwoNumbers(new ListNode(1), node, false);
}


For testing:

private ListNode toListNode(int num) {
    if (num > 0) {
        return new ListNode(num % 10, toListNode(num / 10));
    }
    return new ListNode(0);
}

private int toInt(ListNode node) {
    if (node == null) {
        return 0;
    }
    if (node.next != null) {
        return node.val + 10 * toInt(node.next);
    }
    return node.val;
}

private int addTwoNumbersHelper(int n1, int n2) {
    ListNode l1 = toListNode(n1);
    ListNode l2 = toListNode(n2);
    return toInt(addTwoNumbers(l1, l2));
}

private void assertValid(int n1, int n2) {
    assertEquals(n1 + n2, addTwoNumbersHelper(n1, n2));
}

@Test
public void test_1_99() {
    assertValid(1, 99);
}

@Test
public void test_329_284() {
    assertValid(329, 284);
}

Code Snippets

class ListNode {
    final int val;
    final ListNode next;

    public ListNode(int val) {
        this(val, null);
    }

    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    return addTwoNumbers(l1, l2, false);
}

private ListNode addTwoNumbers(ListNode l1, ListNode l2, boolean carry) {
    if (l1 == null) {
        return withCarryApplied(l2, carry);
    }
    if (l2 == null) {
        return withCarryApplied(l1, carry);
    }

    int sum = l1.val + l2.val + (carry ? 1 : 0);
    boolean nextCarry = sum >= 10;
    int val = nextCarry ? sum - 10 : sum;

    return new ListNode(val, addTwoNumbers(l1.next, l2.next, nextCarry));
}

private ListNode withCarryApplied(ListNode node, boolean carry) {
    if (!carry) {
        return node;
    }
    return addTwoNumbers(new ListNode(1), node, false);
}
private ListNode toListNode(int num) {
    if (num > 0) {
        return new ListNode(num % 10, toListNode(num / 10));
    }
    return new ListNode(0);
}

private int toInt(ListNode node) {
    if (node == null) {
        return 0;
    }
    if (node.next != null) {
        return node.val + 10 * toInt(node.next);
    }
    return node.val;
}

private int addTwoNumbersHelper(int n1, int n2) {
    ListNode l1 = toListNode(n1);
    ListNode l2 = toListNode(n2);
    return toInt(addTwoNumbers(l1, l2));
}

private void assertValid(int n1, int n2) {
    assertEquals(n1 + n2, addTwoNumbersHelper(n1, n2));
}

@Test
public void test_1_99() {
    assertValid(1, 99);
}

@Test
public void test_329_284() {
    assertValid(329, 284);
}

Context

StackExchange Code Review Q#91113, answer score: 11

Revisions (0)

No revisions yet.