算法刷题之路之链表初探(三)
今天来学习的算法题是leecode2链表相加,是一道简单的入门题,但是原子在做的时候其实是有些抓耳挠腮,看了官解之后才恍然大悟!
条件
项目解释
有题目可以知道,我们需要进行的其实是一个数学(十进制计算)问题,当一个链表的数加另一个的链表的数时需要满10进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 head = null, tail = null;
int carry = 0;
while (l1 != null || l2 != null) {
int n1 = l1 != null ? l1.val : 0;
int n2 = l2 != null ? l2.val : 0;
int sum = n1 + n2 + carry;
if (head == null) {
head = tail = new ListNode(sum % 10);
} else {
tail.next = new ListNode(sum % 10);
tail = tail.next;
}
carry = sum / 10;
if (l1 != null) {
l1 = l1.next;
}
if (l2 != null) {
l2 = l2.next;
}
}
if (carry > 0) {
tail.next = new ListNode(carry);
}
return head;
}
}
代码解释
当给定的两个链表分别为 l1 和 l2,其表示的非负整数分别为 235 和 572 时,代码的执行过程如下:
初始化:
head 和 tail 初始化为 null,用来构建结果链表。 carry 初始化为 0,用来记录进位。 循环开始:
进入 while 循环,条件为 l1 != null || l2 != null,只要其中一个链表还有节点,就继续循环。 每一轮循环:
计算当前节点的值: 如果 l1 不为 null,则取 l1.val,否则取 0。 如果 l2 不为 null,则取 l2.val,否则取
0。 将上一轮的进位 carry 加上 n1、n2 得到 sum。 更新进位值 carry 为 sum / 10,即 sum 的十位数。
构建新节点:如果 head 为 null,说明结果链表还没有节点,此时创建新节点 new ListNode(sum % 10),并将 head 和
tail 都指向这个节点。 否则,在 tail.next 处创建新节点 new ListNode(sum % 10),并更新 tail
为新创建的节点。 移动指针:如果 l1 不为 null,将 l1 指向下一个节点。 如果 l2 不为 null,将 l2 指向下一个节点。 循环结束:
循环会重复以上步骤,直到 l1 和 l2 同时为 null。 处理最后的进位:
如果循环结束后,carry 大于 0,说明还有进位需要处理,此时在 tail.next 处创建一个新节点,节点的值为 carry。
返回结果:返回 head,即为最终构建的结果链表的头部。 具体执行过程如下:
初始时 l1 = 235,l2 = 572,carry = 0。 第一轮循环:计算 n1 = 5,n2 = 2,sum = 5 + 2 +
0 = 7,创建节点 7,更新 head 和 tail。 第二轮循环:计算 n1 = 3,n2 = 7,sum = 3 + 7 + 0 =
10,创建节点 0,更新 tail。 第三轮循环:计算 n1 = 2,n2 = 5,sum = 2 + 5 + 1 = 8,创建节点
8,更新 tail。 第四轮循环:l1 和 l2 同时为 null,循环结束。 检查最后的进位 carry = 0,无需额外节点。
因此,最终返回的结果链表为 708。