【体验面试】字节真题:单链表相加
本问题对应课程链接:剑指offer刷题第二期
要求:
1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路。
2、给出你代码所用的时间复杂度和空间复杂度
核心模式做就行,这里我给一个统一的方法题
public ListNode linkedListAdd(ListNode head1, ListNode head2){
}
代码参考
有同学希望我找个代码给大家参考,我从打卡区里选了 @猫猫真可爱 同学的代码给大家参考哦,并且做了一些注释。
// 注意,关于链表节点的定义(ListNode),我这里没有给出来哦
class SolutionAdd {
// 反转链表
public ListNode reverseList(ListNode node){
ListNode pre = null;
ListNode q= null;
while (node != null) {
q= node.next;
node.next = pre;
pre = node;
node = q;
}
return pre;
}
// 单链表相加
public ListNode addTwoNumbers(ListNode head1, ListNode head2) {
// 虚拟头节点
ListNode listNode = new ListNode(0);
ListNode p = listNode;
// sum 用来存放进位
int sum = 0;
while (head1 != null || head2 != null || sum!=0) {
if (head1 != null) {
sum += head1.val;
head1 = head1.next;
}
if (head2 != null) {
sum += head2.val;
head2 = head2.next;
}
p.next = new ListNode(sum % 10);
sum = sum / 10;
p = p.next;
}
return listNode.next;
}
}
时间复杂度:O(n+m)
空间复杂度:O(1)
共以下 53 个回答
时间复杂度O(N)
空间复杂度O(N)
用哑节点去定位,翻转进位再翻转
思路:就是
24.反转链表和2.两数相加的综合题Time:O(n + m)
Space:O(1)
该问题主要需要翻转连接进行计算
时间复杂度:O(n+m)
空间复杂度:O(1)
有思路 但是没写出来
时间复杂度:O(n+m)
空间复杂度:O(1)
思路:单链表相加,两个链表的长短不一,但是我们将两个链表分别翻转后,个位就是从头节点开始的节点了,
这里需要注意,要声明一个变量记录进位。然后每次两个链表相加时都要再加上进位的数字。
最后移动指针的时候要先判断这两个链表目前所在的结点是否为空,若为空则不能移动指针(这样就能避免空指针异常了)。
根据帅老师的提示,先原地反转直接解决了原本的向前进位的问题,此时只需next节点进位即可。采用了ret的链表直接上长度比较长的,在其基础之上相加另一条链表。最后再翻转返回。
时间复杂度O(max(n+m))
空间复杂度O(1)
思路对了,代码水平不够
复现的参考代码
时间 N 空间 1
时间复杂度:O(max(n+m))
空间复杂度:O(1)
先反转链表再进行相加操作,注意进位问题
方法一:反转链表再相加
1. 时间复杂度:O(max(n, m))
2. 空间复杂度:O(n+m)
3. 代码
反转链表 然后再相加, 昨天想法是在原有长链表的基础上去添加元素,但无法解决创建多(>2)结点的问题,改变思路,重新建立一个新链表添加
不知道对不对,先打卡一下
https://leetcode.cn/problems/lMSNwu/
时间复杂度O(max(l1,l2))
空间复杂度O(1)
反转链表,然后遍历相加,注意进位。
见链接
分析
定义一个逆序函数,该函数使用的递归,先将两个链表逆序,然后同位相加大于等于10,则进一位该位取余,别忘了特殊情况比如9944链表和链表56,最后进的一位再建立一个值为1的节点,然后连接上,最后再将相加后的链表逆序得到结果,具体详细见代码,时间空间复杂度都为O(n)。
代码
思路:反转链表+链表加和+再反转
这个是比较麻烦的方式,最好的方式是将两个链表压入栈里。在栈里进行加法运算,最后再输出
思路:先将两个链表反转,直接模拟,中间用一个int型carry记录前一位两个数相加是否产生进位,我是直接在链表1上直接修改,所以空间复杂度为O(1),时间复杂度为O(n)。特殊输入:[[1],[9,9,9]],[[5],[5]],[[9,1],[1,9]]。
先反转,然后sum存val值,tag标记有无标记为,因为加法,进位最多为1,所以tag = 0|| 1就行。
和两数相加思路基本一样,只是多了反转的操作
时间复杂度O(max{m,n}) 额外空间复杂度O(1)
时间复杂度 n
空间复杂度 1
时间复杂度:O(n)
空间复杂度:O(1)
解体方法:按照提示先进行反转,再进行加法计算,计算时分别考虑其中一个为空链表以及两链表长度不相等的情况,再将计算结果反转
时间复杂度:O(n)
空间复杂度:O(1)
存在以下几种解法:
1. 逆转后相加再逆转回来
2. 使用栈(凡是逆序相关的题目均可以有意识地考虑)
3.遍历后获取两个length,然后将顺序对齐(快慢指针,慢指针指向上一个小于9的位置),这个解法比较复杂,但是情况并没有多少优化。
时间复杂度 O(n)
时间复杂度O(N)
空间复杂度O(1) cur,pre使用额外空间
反转链表,操作相加,最后反转结果,自己测试了几个位数不同的,有进位的貌似都没有问题了。
下面代码
复杂度分析:
时间复杂度:O(max{m,n}),空间复杂度:O(1)
分析:
正常计算
1 2 3 4
3 4
1 2 6 8
思路结果
4 3 2 1
4 3
8 6 2 1
1 2 6 8
就是单向链表的翻转,然后进行计算,然后在翻转,即可得出答案
反转链表
时间复杂度O(max(n,m))
空间复杂度O(1)
时间复杂度:O(max(m,n)),空间复杂度:O(1)
对应解决的是力扣上的https://leetcode.cn/problems/lMSNwu/
反转链表
当时只看到这一页,题目意思理解错了,现在修改一下,本题的题意和 leetcode https://leetcode.cn/problems/sum-lists-lcci/ 基本一致,除了这道 leetcode 中的链表默认已经翻转过。
可以讲一下你的思路哦。