相信看了这个标题的同学,对这道题以已经非常不陌生了,就是leecode当中的第二题,之所以要单独的写一写主要对我来说,里面涉及到有一个知识点比较重要,也有几个小技巧,这里我也权当记忆巩固了,这道题也曾被Micosoft, Amazon, Bloomberg, Airbnb, Adobe作为经典面试题。
题目
给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式 存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
通俗的讲就是从两个非空的链表获取节点值做一个加法,生成新的一个链表。根据事例提出几个问题:
①怎么确定第一个节点?
②假如我们确定了头节点是7,当我们移向下一个节点的时候,怎么留住之前的节点7呢?
dummyHead虚拟头节点:
对于单链表来说,唯一能让它保持联系就是它的头节点,对于事例来说7就是我们的头节点,但是在计算出头节点7之前,我们不知道头节点是什么。这里我们有一个通用的做法:建立一个dummyHead,我们初始一个头节点是0,在计算完链表之后,我们只需要获取dummyHead.next,就是我们想要的链表。
ListNode dummyHead = new ListNode(0);
指针节点:
为了解决第二个问题,当获取到两个链表的头节点2和5计算得到dummyHead的 头节点指向了7,但是我们需要移动dummyHead = dummyHead .next 到下一个节 点,才能对两个链表的4和6计算赋值给dummyHead,这样的话dummyHead的头节点 7相当于就被移除了,所以我们需要一个指针节点curr来指向dummyHead,当curr 移动的时候,dummyhead始终保持节点。
参考代码
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0); // 小技巧
ListNode p = l1, q = l2, curr = dummyHead;// 指向节点
int carry = 0;// 进位
while (p != null || q != null) {
int x = (p != null) ? p.val : 0;
int y = (q != null) ? q.val : 0;
int sum = carry + x + y;
carry = sum / 10;
curr.next = new ListNode(sum % 10); //
curr = curr.next;//
if (p != null) p = p.next; // 进入下一个循环
if (q != null) q = q.next;
}
if (carry > 0) {
curr.next = new ListNode(carry); // 赋值给下一个
}
return dummyHead.next;
}
测试用例:
@Test
public void isAddTwoNumbers() {
ListNode l1 = new ListNode(2);
l1.next = new ListNode(4);
l1.next.next = new ListNode(3);
ListNode l2 = new ListNode(5);
l2.next = new ListNode(6);
l2.next.next = new ListNode(4);
ListNode listNode = addTwoNumbers(l1, l2);
Assert.assertNotNull(listNode.val);
}
热门推荐:
万字长文浅析:Epoll与Java Nio的那些事儿
万字图文浅析 :ThreadPoolExecutor线程池
万字解析:最近服务准备上线,统一对微服务增加JVM参数
万文长字分析:想进大厂,你不得不掌握的CPU缓存基础
文末福利,最近整理一份面试资料《Java面试通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:关注微信公众号【汀雨笔记】并回复 interview 领取,更多内容陆续奉上。