首页 > 其他分享 >LC1171. 从链表中删去总和值为零的连续节点

LC1171. 从链表中删去总和值为零的连续节点

时间:2023-06-12 16:22:05浏览次数:119  
标签:node 前缀 值为 Node4 链表 LC1171 Node1 节点

题目来源于力扣题库,题目链接:LC1171.从链表中删去总和值为零的连续节点

Q:给你一个链表的头节点 head,请你编写代码,反复删去链表中由 总和 值为 0连续节点组成的序列直到不存在这样的序列为止

删除完毕后,请你返回最终结果链表的头节点。

 你可以返回任何满足题目要求的答案。

(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)

示例:

示例 1:
输入:head = [1,2,-3,3,1]
输出:[3,1]
提示:答案 [1,2,1] 也是正确的。
示例 2:
输入:head = [1,2,3,-3,4]
输出:[1,2,4]
示例 3:
输入:head = [1,2,3,-3,-2]
输出:[1]

A:分析:通过阅读题目,我们可以得到的较为重要的信息就是“反复删去”、“总和为0”、“连续节点组成的序列”、“直到不存在为止”这类的关键字眼,那么我们接下来构思解决方案的时候肯定是要围绕着解决这几个关键字来进行的。

  首先,碰到链表类的题目,大概率是要手动去创建一个哑结点的,并将其next指针指向头结点。本题给了一个头结点且又是涉及到删除操作,所以创建哑结点(dummyNode)刻不容缓;其次,反复删除一定是要设计到一个循环的,从首至尾,并非找到一组总和值为0的连续节点组成的序列就结束了,而是要不断的寻找,直到不存在这样的序列为止。谈到“这样的序列”,我们也要想一想,总和为0的连续节点组成的序列会有哪些情况?第一种情况,单个节点的val就是0的;第二种情况多个(大于1)连续节点的val之和为0的。最后,一个较为重要的问题就是如何去求连续节点组成序列的“总和”。我们可以举个例子来看看用什么方法,现假设一共有5个节点,即[Node1(1, Node2), Node2(2, Node3), Node3(1, Node4), Node4(-3, Node5), Node5(10, Null)],这里我们定义一个节点为Node(val, next)的形式,则很显然,中间的三个连续节点Node2、Node3和Node4的和是为0的,所以接下来要做的就是将移动Node1的next指针,使其指向Node5,即可完成删除。但是,如何判断呢?怎么才能知道从Node2到Node5的和值为0呢?“前缀和”(前缀和指一个数组的某下标之前的所有数组元素的和(包含其自身))可以去解决这个问题,因为前缀和是具有记忆作用的,想象一下,当两个节点的前缀和相同,那么是不是就说明了存在连续的和为0的节点序列了呀。

  现举例模拟上述思想,我们使用了哈希表来存储key为前缀和prefix,value为节点Node,初始化一个哑结点为dummyNode,并将其值val设置为0。我们还是利用上述给出的那个链表,并在其基础上加上我们新创建的哑结点,则链表的形式是[dummyNode(0, Node1), Node1(1, Node2), Node2(2, Node3), Node3(1, Node4), Node4(-3, Node5), Node5(10, Null)],接下来开始初始化前缀和并遍历这个链表,初始化prefix = 0为前缀和。

  我们可以得到:

  dummyNode的前缀和为0 + 0,

  Node1的前缀和为0 + 0 + 1 = 1,

  Node2的前缀和为0 + 0 + 1 + 2 = 3,

  Node3的前缀和为0 + 0 + 1 + 2 + 1 = 4,

  Node4的前缀和为0 + 0 + 1 + 2 + 1 + (-3) = 1,

  Node5的前缀和为0 + 0 + 1 + 2 + 1 + (-3) + 10 = 11,

  在一一得到每个节点对应的前缀和后并将其加入到哈希表中Map<Integer, Node>,这里就会出现一个覆盖节点的操作,就是说当Node1节点存储到哈希表后,再存储Node4的时候,Node4会将Node1给覆盖掉,换句话说,遇到具有相同前缀和的节点,我们只存储最后的那一个,这也是为了我们第二步遍历时方便进行删除操作而设计的。那么最终我们的哈希表中就有了HashMap[(0, dummyNode), (1, Node4), (3, Node2), (4, Node3), (11, Node5)]。

  我们为了进行删除操作需要进行二次遍历节点并统计前缀和,当第二次遍历时,如果哈希表中存在与当前遍历的节点具有相同的前缀和的节点,我们就进行删除操作。比如我们第二次遍历到了Node1,而哈希表中正好存在与Node1具有相同前缀和的Node4节点,那么直接将Node1的next指针指向Node4的下一个节点即可,至此就找到了一组总和为0的连续的节点序列,也就完成了删除,将Node1和Node5之间具有的和为0的连续节点序列给删除掉了。

  以下是Java代码,仅供参考:

package algo;

import java.util.HashMap;
import java.util.Map;

public class removeZeroSumSublistsSolution_1171 {
    public ListNode removeZeroSumSublists(ListNode head){
        ListNode dummyNode = new ListNode(0);
        dummyNode.next = head;

        Map<Integer, ListNode> map = new HashMap<>(); // 构建一个哈希表,存储<prefix, Node>的键值对
        int prefix = 0; // 初始前缀和为0
        for(ListNode node = dummyNode; node != null; node = node.next){
            prefix += node.val; // 第一次统计前缀和
            map.put(prefix, node); // 覆盖操作
        }
        prefix = 0; // 重新初始化前缀和为0
        for(ListNode node = dummyNode; node != null; node = node.next){ 
            prefix += node.val; // 第二次统计前缀和
            node.next = map.get(prefix).next; // 删除操作
        }
        return dummyNode.next; // 返回head
    }
}

 

标签:node,前缀,值为,Node4,链表,LC1171,Node1,节点
From: https://www.cnblogs.com/fxy0715/p/17475094.html

相关文章

  • 【数据结构】单链表
    前言<fontcolor=bluesize=4>在学习数据结构时,单链表可谓是第一个需要跨越的台阶。</font>从C语言到数据结构,单链表能够真正的反映我们C语言到底学的扎不扎实,那是因为,单链表对于C语言中的指针,结构体,以及函数模块的实现有较高的要求。因此,通过本章的学习,要是能够自我实现单......
  • leetcode 1171. 从链表中删去总和值为零的连续节点
    给你一个链表的头节点 head,请你编写代码,反复删去链表中由总和 值为0的连续节点组成的序列,直到不存在这样的序列为止。删除完毕后,请你返回最终结果链表的头节点。你可以返回任何满足题目要求的答案。(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)示例1:输入:he......
  • Leetcode 1171. 从链表中删去总和值为零的连续节点
    题目:给你一个链表的头节点 head,请你编写代码,反复删去链表中由总和 值为0的连续节点组成的序列,直到不存在这样的序列为止。删除完毕后,请你返回最终结果链表的头节点。你可以返回任何满足题目要求的答案。(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)难......
  • 根据已有链表中的元素进行排序
    思想为先将链表中的每一个节点映射到一个链表节点为变量的数组里,在根据节点的元素进行排序,本程序为ave,过程中将数组变量排序,最后重新生成链voidpaixu(LinkListhead)//从大到小{intlength=len(head),i=0,j=0,sum1[length],n1;LinkListsum[length];LinkListpa=hea......
  • 第四天打卡|24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 面试题 02.07.
    24.两两交换链表中的节点:简单的交换 19.删除链表的倒数第N个节点: ●  面试题 02.07. 链表相交:这题没看过答案真的写不出来。太巧妙了  142.环形链表II:这题写过但是忘记怎么解的了还是看的答案。下次不能忘记  ......
  • 2023.6.11 从链表中删去总和值为0的节点
    对一个序列进行前缀和处理,假设p处前缀和与q处前缀和相等,说明\((p,q)\)之间的序列和为0。因此我们可以遍历一次链表,预处理出前缀和,同时用哈希表记录,哈希表的key为前缀和,value为所处节点。遇到相同的key时,直接覆盖,这样哈希表存储的就是前缀和为key的最后一个节点。第二次遍历......
  • #yyds干货盘点# LeetCode程序员面试金典:环形链表
    题目:给你一个链表的头节点head,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引从0开始)。注意:pos不作为参数进行传递 。仅仅是为了标识链......
  • #yyds干货盘点# LeetCode程序员面试金典:移除链表元素
    1.简述:给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。 示例1:输入:head=[1,2,6,3,4,5,6],val=6输出:[1,2,3,4,5]示例2:输入:head=[],val=1输出:[]示例3:输入:head=[7,7,7,7],val=7输出:[]2.代码实现:class......
  • 《数据结构与算法》之队列与链表复习
    导言:我们在上一次学习了堆栈的数据结构以后,可以了解到它是受限制的操作,比如我们操作只能在栈顶,现在我们要学习的东西叫做队列,它也是受限制的一种数据结构,它的特点是队头只出数据,而队尾只入数据,它的结构就和它的名字,像我们平时排队一样先来的人肯定要先服务啊,所以它的英文叫做Fri......
  • 13.双向链表的算法实现
      单链表中每个结点除了存储自身数据之后,还存储了下一个结点的地址,因此可以轻松访问下一个结点,以及后面的后继结点,但是如果想访问前面的结点就不行了,再也回不去了。  例如删除结点p时,要先找到它的前一个结点q,然后才能删掉p结点,单向链表只能往后走,不能向前走。如果需要向前走......