patternjavaModerate
Sum two linked lists
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 SumTwoUtils {
public String printLinkedList(ListNode l){
StringBuffer s = new StringBuffer();
while (l != null){
s.append(l.ge
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.