0
点赞
收藏
分享

微信扫一扫

删去总和值为零的连续节点(前缀和)

删去总和值为零的连续节点(前缀和)

题目描述

示例

image-20220203122725233

解决

题目翻译

由于题目比较难理解,所以首先将题目用通俗易懂的语言描述一下:

如下图所示,由于子链3 -3和为0,所以,我们应当知道被断开子链表的前驱节点 2,将其连接到被断开子链表的后继节点 5。

image-20220203125052081

思路分析

​ 通过计算前缀和,我们可以发现。红色部分和为3,橙色部分和为0,红色部分加上橙色部分后和还是为3,所以橙色部分就是要被删除的子链

​ 如何删除呢?

​ 将红色部分的最后一个节点(要删除子链的前驱节点)连接到橙色部分最后一个节点的下一个节点(要删除子链的后继节点)即可。

image-20220203125957268

步骤

  • 利用map集合保存当前遍历节点cur及其前缀和sum
    • 如果map集合已经存在该前缀和,那么找到已存在的节点,让其连接到当前节点的下一节点,然后删除断开子链中各个节点的前缀和(更新map集合)
    • 如果map集合中不存在,那么将其加入

代码实现

public ListNode removeZeroSumSublists(ListNode head)
{
    HashMap<Integer, ListNode> map = new HashMap<>();
    ListNode newHead = new ListNode(0, head);
    map.put(0, newHead);
    ListNode cur = head;
    int sum = 0;
    while (cur != null)
    {
        sum += cur.val;
        if (map.containsKey(sum))
        {
            //1.删除子链
            ListNode subListPrev = map.get(sum);//获取要删除子链的前驱节点
            ListNode subListCur = subListPrev.next;//子链的遍历节点,初始值为子链的头节点
            subListPrev.next = cur.next;//将子链的前驱节点连接到当前节点的下一节点
            //2.更新map
            int subListSum = sum;//保存当前和
            while (subListCur != cur)//直到遍历到要删除子链的后继节点
            {
                subListSum += subListCur.val;
                map.remove(subListSum);//移除map中保存的子链前缀和
                subListCur = subListCur.next;
            }
        }
        else
        {
            map.put(sum, cur);//添加当前节点及前缀和
        }
        cur = cur.next;//指针后移
    }
    return newHead.next;
}
        }
        cur = cur.next;//指针后移
    }
    return newHead.next;
}
举报

相关推荐

0 条评论