2:两数相加
题目核心是:
两个链表表示两个整数
每一位存一个数字
数字是倒序存储
要求返回它们的和
例如:
l1 = [2,4,3]
l2 = [5,6,4]
表示数字:
342
465
因为:
2 -> 个位
4 -> 十位
3 -> 百位
计算:
342 + 465 = 807
返回:
7,0,8
分析:
题目说的倒叙存储,很巧妙的符合了个十百位的数学计算
通过这一特点,我们想到了链表
为什么链表合适
当我们遍历链表时,从头到尾的遍历正好等于我们从个位开始计算的过程。
算法流程
1.创建一个结果链表
2.同时遍历两个链表
3.计算档当前位和进位
4.保存结果节点
这个过程我们需要定义的是:
创建一个结果链表(dummy节点)
进位记录:carry(sum/10)
当前位:cur(sum%10)
代码实现
java
//创建一个虚拟头节点dummy
ListNode dummy=new ListNode(0);
//指针cur 指向 dummy 节点
ListNode cur=dummy;
int carry=0;
while(l1!=null||l2!=null||carry!=0){
int x=(l1!=null)?l1.val:0;
int y=(l2!=null)?l2.val:0;
int sum=x+y+carry;
//获取进位数
carry=sum/10;
//创建新节点
cur.next=new ListNode(sum%10);
//指针向后移动(从dummy指向后一位)
cur=cur.next;
if(l1!=null)l1=l1.next;
if(l2!=null)l2=l2.next;
}
return dummy.next;
19 删除链表中 倒数第 n 个节点
题目核心是:
删除链表中 倒数第 n 个节点,并返回链表头节点。
也许第一反应是:
1 先遍历链表求长度
2 找到正数第 (len-n) 个节点
3 删除
但是这样遍历了两次,导致超时。
于是我们寻找到了:快慢指针的方式。
核心思想:快慢指针
流程:
先让fast指针先走n步
然后让fast和slow一起走
当fast达到末尾,slow在被删除元素的前面一个节点。
我们更改指针
java
slow.next = slow.next.next
就达到了删除操作。
我们需要用到dummy节点
原因是:
如果我们删除的元素是第一个节点,没有dummy就很难处理。
有dummy:dummy -> 1 -> 2
代码实现
java
ListNode dummmy=new ListNode(0);
dummy.next=head;
//不可以是head
ListNode fast=dummy;
ListNode fast=dummy;
//先让fast走n步
for(int i=0;i<n;i++){
fast=fast.next;
}
//一起走
while(fast!=null){
slow=slow.next;
fast=fast.next;
}
//删除节点
slow.next=slow.next.next;
return dummy.next;