今日题目
本系列所选题目均来自力扣或者牛客网站. 所选题目主要是以其中的简单题为主, 中等题为辅, 包含少数困难题(原因是: 本人目前能力还不够~ ). 开展这个系列的目的是督促自己, 在暑假的时间里也要保持有一定的刷题量, 拒绝摆烂~
话不多说, 直接开刷~~
从链表中删去总和值为零的连续节点
题目描述: 给你一个链表的头节点 head,请你编写代码,反复删去链表中由 总和 值为 0 的连续节点组成的序列,直到不存在这样的序列为止。
删除完毕后,请你返回最终结果链表的头节点。
示例:
输入:head = [1,2,-3,3,1]
输出:[3,1] (因为1+2-3总和是0, 删除这些节点, 剩下3, 1).
解题思路:
(1) 这种类型的题也是我第一次碰到的, 刚开始我一直都在用前后指针的方法来解这道题, 结果要么是报错, 要么是部分示例没有通过… 于是看了看一些大佬的题解 — 前缀和+哈希表, 说实话, 这还是我第一次见到这样的解法, 有点被震惊到.
(2) 记录链表中每个节点的前缀和, 将它们存到哈希表里面. 具体实现过程是 — 第一次遍历: 计算每个节点的前缀和,存到哈希表里面去(就算某个节点的前缀和是相同也没事,哈希表直接记录前缀和相同的最后一个节点位置).
(3) 重新遍历整个链表, 看看在哈希表中是否有相同的前缀和存在, 如若有, 则找到哈希表中的这个节点, 然后直接跳过中间的所有节点(包括哈希表中存的这个节点本身), 然后从这里开始接着往下遍历; 如若没有, 那么直接往下遍历即可. 具体实现过程是 — 第二次遍历: 计算当前节点的前缀和,在哈希表中查看是否有前缀和相等的节点(这里的节点直接就是相同前缀和节点的最后一个),这样就可以直接跳过中间的元素(其实就相当于删除掉了这些节点).
(4) 最后形成的新的链表就是目标链表.
实现代码:
class Solution {
public ListNode removeZeroSumSublists(ListNode head) {
if(head==null){
return null;
}
ListNode dummy=new ListNode(0);
dummy.next=head;
Map<Integer,ListNode> map=new HashMap<>();
// 第一次遍历
int sum=0;
ListNode cur=dummy;
while(cur!=null){
sum+=cur.val;
map.put(sum,cur);
cur=cur.next;
}
// 第二次遍历
sum=0;
cur=dummy;
while(cur!=null){
sum+=cur.val;
cur.next=map.get(sum).next;
cur=cur.next;
}
return dummy.next;
}
}
两数相加
题目描述: 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
解题思路:
(1) 首先定义一个新的链表来存储最终的结果.
(2) 同时将 l1 和 l2 进行遍历, 相加对应节点的val值, 如若相加之后的结果不大于10, 则直接将相加之后的结果存到新的链表当中去; 否则, 则将相加之后的结果减去10后, 存到新的链表中去, 同时在进行下一次遍历的时候, val值相加之后的结果加1… 如此往复, 直到 l1 和 l2 之间有一方(或两方)的链表遍历完, 跳出这个操作.
(3) 如若 l1 没有遍历完, 则将 l1 剩下的节点全部拼接到新的链表后面; 反之 l2 没遍历完, 将 l2 剩下的节点全部拼接到新的链表后面. 这里要注意: 在拼接的时候, 还是需要判断有没有需要进位的, 判断方法也是跟之前判断进位的操作基本是类似.
(4) 如若是最后一个节点(也就是数字最高位)需要进位, 那么就需要在链表的最后面加上一个val值为1的节点(补全最高位), 最后返回这个链表即可.
实现代码:
class Solution {
public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode head=new ListNode(0);
ListNode cur=head;
boolean flag=false;
while(l1!=null&&l2!=null&&cur!=null){
ListNode curNext=new ListNode(0);
cur.next=curNext;
int tmp=l1.val+l2.val;
if(flag){
tmp+=1;
flag=false;
}
if(tmp>=10){
tmp-=10;
flag=true;
}
curNext.val=tmp;
l1=l1.next;
l2=l2.next;
cur=cur.next;
}
while(l1!=null){
cur.next=l1;
if(flag){
l1.val+=1;
flag=false;
}
if(l1.val>=10){
l1.val-=10;
flag=true;
}
cur=cur.next;
l1=l1.next;
}
while(l2!=null){
cur.next=l2;
if(flag){
l2.val+=1;
flag=false;
}
if(l2.val>=10){
l2.val-=10;
flag=true;
}
cur=cur.next;
l2=l2.next;
}
if(flag){
cur.next=new ListNode(1);
}
return head.next;
}
}