1171. 从链表中删去总和值为零的连续节点 - 力扣(Leetcode)
累加数据和重复出现相同时,说明从相同和的第一次出现的下一个结点到最后一次相同累加数据的结点和为0,删除这段结点串、
给你一个链表的头节点 head
,请你编写代码,反复删去链表中由 总和 值为 0
的连续节点组成的序列,直到不存在这样的序列为止。
删除完毕后,请你返回最终结果链表的头节点。
注意审题:删除连续结点总和为0的结点,这里的重点我们需要放到连续,这说明我们是需要删除这一块空间数据。
假设我们对该链表进行操作,因为这是连续的结点和为0,需要删除,其实我们可以看成,删除链表中的一段结点。
其实我们现在就是需要这段被删除的数据的最后一个结点与第一个结点之前的数据。
观察数据和
我们需要将1结点的(1)->next=(-5)->next
我们需要保存所有累加的数据。
遍历链表,保存键值对first(sum_int)与second(ListNode*)。
持续遍历到(-5);
我们的sum==X+1的数据已经存在,这时候sum-5后有一次sum==X+1的key值这个时候改变映射表中的x+1的second数据,这样就保存了我们需要删除的数据再映射表中了。
这样前面的sum保存的指针数据(1),就被hash修改成(5);如果后面的sum依旧出现sum==X+1的情况再一次覆盖,将删除段扩大。
继续遍历,到结束。
这样我们就获得了一个hash映射表,怎么用呢?
我们重新遍历链表
重新累加数据。cur又到了(1)结点,sum=X+1;
判断我们的hash[sum]是否等于当前node,如果不等于说明当前结点开始后面有一段数据和为0,直到hash[sum]结点,hash[sum]就是需要删除段的最后一个结点,当前结点cur的下一结点是删除段的第一个结点。
所以不等于时候,我们需要把当前结点的next等于hash[sum].next;
为了防止出现头删情况,我们增加一个hhead头结点保存头部链接,头节点数据不影响我们的结果。
代码:
class Solution {
public:
ListNode* removeZeroSumSublists(ListNode* head) {
ListNode* dummy = new ListNode(1);
dummy->next = head;
int prefix = 0;
unordered_map<int, ListNode*> seen;
for (ListNode* node = dummy; node; node = node->next) {
prefix += node->val;
seen[prefix] = node;
}
prefix = 0;
for (ListNode* node = dummy; node; node = node->next) {
prefix += node->val;
if(node!=seen[prefix])
node->next = seen[prefix]->next;
}
return dummy->next;
}
};