前言
Algorithms + Data Structures = Programs.
————Pascal之父 Nicklaus Wirth
算法 + 数据结构 = 程序
坚持刷算法题,变得更强!
(如果对你有帮助的话,可以帮忙点赞一下哦)
题目及详解
解析
解题目标:我们最后返回的是一个新链表,这个链表的逆序等于本来两个链表逆序相加,所以被称为两数相加。 难度中等,且听细细道来~
思路:看到题目是不是有点不知所措,难道我应该把链表的表头开始存下来,存到数组里或存到哪里,然后再让其相加,再逆序一下得到新数组或其他?
没那么麻烦。想想你算加法的时候咋算的?是不是从个位数开始相加呀?那你看这个这俩链表的表头,不就是你要的个位数吗?
重点来了,从表头开始相加,存到一个新链表里,重要的是如果表头两个数相加超过10咋办?那你是不是要进1,比如表头为5+7,那你是不是(5+7)%10 = 2,把2存到新链表表头,把(5+7)/10 = 1,把1进入下一位相加,问题就迎刃而解。
代码实现步骤详解
接下来我们看一下题目所给的代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
}
}
上面给了一个ListNode类,里面有几个方法,下面也给了俩参数l1和l2,那么我们就可以用这两个参数代表两个链表各自的表头,然后用l1.next和l2.next调用各自链表接下来的数。
接下来,我们要创建三个变量,一个dummy作为新链表,一个curr作为新链表指针,一个carry用来接收5+6这种需要向下一位进1的情况。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode curr = dummy;
int carry = 0;
}
}
接下来我们的工作就是遍历两个链表让他们从表头开始相加,不由自主地想到需要用到一个循环,但什么时候结束呢? 既然l1和l2用来指向两个链表每一位,那么我们就可以说当两个链表都指向空的时候,循环结束。
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode curr = dummy;
int carry = 0;
while(l1 != null || l2 != null){
int x = l1 == null ? 0 : l1.val;
int y = l2 == null ? 0 : l2.val;
int sum = x+y+carry;
curr.next = new ListNode(sum%10);
curr = curr.next;
carry = sum / 10;
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
}
}
int x和int y那里是最早从C语言中就见过的表达式,他的意思是如果l1等于空,则把0给x,不为空,则把l1.val(题目给的链表数)赋给x。当然y同理。
然后最后两个if语句,举个栗子,2+12,第一次循环l1指向的数据2,然后判断l1不为空,则l1指向下一位,下一位就是空了,第二次循环的时候就会判断为空,不再继续改变l1的指向。
当然,退出循环之后别忘记还有个carry,比如456+789,加到百位的时候是不是又要进1?但你l1和l2都指向空了,那就另行判断carry是否为0,不为0,记得加1。最后返回新链表dummy。
完整解题代码
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode();
ListNode curr = dummy;
int carry = 0;
while(l1 != null || l2 != null){
int x = l1 == null ? 0 : l1.val;
int y = l2 == null ? 0 : l2.val;
int sum = x+y+carry;
curr.next = new ListNode(sum%10);
curr = curr.next;
carry = sum / 10;
if (l1 != null) l1 = l1.next;
if (l2 != null) l2 = l2.next;
}
if (carry != 0)curr.next = new ListNode(carry);
return dummy.next;
}
}