一、问题描述
给定两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
1 2 3
| 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
|
提示:
- 每个链表中的节点数在范围
[1, 100]
内
0 <= Node.val <= 9
- 题目数据保证列表表示的数字不含前导零
二、解决方案
题目要求的返回结果为链表的头节点,需要遍历两个链表,在遍历两个链表的过程中,计算结果链表中各个位置的值。
链表中每个位置的取值为 0 到 9,所以每个位置两个值相加范围在 0 到 18,当计算结果大于等于 10 时,需要进位。当前位置保留的值为和除以 10 的余数,下一个节点的初始值为 1。
三、Java 代码实现
ListNode
节点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Data @NoArgsConstructor public class ListNode {
int val;
ListNode next;
public ListNode(int val) { this.val = val; }
public ListNode(int val, ListNode next) { this.val = val; this.next = next; }
@Override public String toString() { return val + "" + (next == null ? "" : next); } }
|
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public ListNode addTwoNumbers2(ListNode l1, ListNode l2) { ListNode resultNode = new ListNode(); ListNode tempNode = resultNode; while (l1 != null || l2 != null) { int num = l1 == null ? 0 : l1.val; int num2 = l2 == null ? 0 : l2.val; int sum = num + num2 + tempNode.val; tempNode.val = sum % 10; if (l1 != null) { l1 = l1.next; } if (l2 != null) { l2 = l2.next; } if (l1 != null || l2 != null || sum >= 10) { tempNode.next = new ListNode(sum / 10); tempNode = tempNode.next; } } return resultNode; }
|
递归实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public ListNode addTwoNumbersRecursion(ListNode l1, ListNode l2) {
if (l1 == null) { return l2; } if (l2 == null) { return l1; }
int sum = l1.val + l2.val; ListNode resultNode = new ListNode(sum % 10); resultNode.next = addTwoNumbersRecursion(l1.next, l2.next); if (sum >= 10) { resultNode.next = addTwoNumbersRecursion(resultNode.next, new ListNode(1)); } return resultNode; }
|
Junit 5 测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| @Slf4j class SolutionTest {
@Data @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor private static class InputOutput {
private ListNode inputListNode;
private ListNode inputListNode2;
private ListNode resultListNode; }
private final Solution solution = new Solution();
private final List<InputOutput> inputOutputList = List.of( new InputOutput( initListNodeByString(342), initListNodeByString(465), initListNodeByString(807) ), new InputOutput( initListNodeByString(0), initListNodeByString(0), initListNodeByString(0) ), new InputOutput( initListNodeByString(9_999_999), initListNodeByString(9_999), initListNodeByString(10_009_998) ) );
private ListNode initListNodeByString (int num) { String numString = String.valueOf(num); ListNode resultListNode = new ListNode(); ListNode tempNode = resultListNode; for (int i = numString.length() - 1; i >= 0; i--) { char c = numString.charAt(i); tempNode.val = Integer.parseInt(String.valueOf(c)); if (i > 0) { tempNode = tempNode.next = new ListNode(); } } return resultListNode; }
@Test void initListNodeByString() { Assertions.assertEquals("243", initListNodeByString(342).toString()); Assertions.assertEquals("0", initListNodeByString(0).toString()); Assertions.assertEquals("01", initListNodeByString(10).toString()); }
@Test void testListNodeToString() { System.out.println(inputOutputList.getFirst().inputListNode.toString()); }
@Test void addTwoNumbers2() { for (int i = 0; i < inputOutputList.size(); i++) { InputOutput inputOutput = inputOutputList.get(i); ListNode listNode = solution.addTwoNumbers2(inputOutput.inputListNode, inputOutput.inputListNode2); Assertions.assertEquals(StringUtils.reverse(inputOutput.resultListNode.toString()), StringUtils.reverse(listNode.toString())); } }
@Test void addTwoNumbers2deleteRedundantVar() { for (int i = 0; i < inputOutputList.size(); i++) { InputOutput inputOutput = inputOutputList.get(i); ListNode listNode = solution.addTwoNumbers2deleteRedundantVar(inputOutput.inputListNode, inputOutput.inputListNode2); Assertions.assertEquals(StringUtils.reverse(inputOutput.resultListNode.toString()), StringUtils.reverse(listNode.toString())); } }
@Test void addTwoNumbers3() { for (int i = 0; i < inputOutputList.size(); i++) { InputOutput inputOutput = inputOutputList.get(i); ListNode listNode = solution.addTwoNumbers3(inputOutput.inputListNode, inputOutput.inputListNode2); Assertions.assertEquals(StringUtils.reverse(inputOutput.resultListNode.toString()), StringUtils.reverse(listNode.toString())); } }
@Test void addTwoNumbersRecursion() { for (int i = 0; i < inputOutputList.size(); i++) { InputOutput inputOutput = inputOutputList.get(i); ListNode listNode = solution.addTwoNumbersRecursion(inputOutput.inputListNode, inputOutput.inputListNode2); Assertions.assertEquals(StringUtils.reverse(inputOutput.resultListNode.toString()), StringUtils.reverse(listNode.toString())); } }
}
|
相关链接
OB links
[[取模和求余运算的不同]]
#LeetCode #算法