11. <tag-链表和前缀和, 哈希表>lt.1171- 从链表中删去总和值为零的连续节点
lt.1171- 从链表中删去总和值为零的连续节点
[案例需求]

[思路分析]

[代码实现]
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeZeroSumSublists(ListNode head) {
//前缀和的一个应用, 为什么会想到用前缀和, 因为是题目要求是一些子区间的加加减减,
// 题目要求是去除掉和为0的结点, 所以前后的值相同的两个前缀和, 这两个前缀和之间的数之和一定是0
//对于链表, 来回的遍历结点无非是很麻烦的, 要想实现对链表的自由遍历, 可以使用哈希表存储结点
// 所以本题, 用哈希表存储<前缀和, 结点>, 由于哈希表中key相同的两个映射, 会自动覆盖值, 所以
// 我们遍历完成一次链表之后, 哈希表中的结点都是各种组合不为0的结点;
Map<Integer, ListNode> map = new HashMap<>();
ListNode temp = head;
// Q: 链表的前缀和如何计算?
int preSum = 0;
while(temp != null){
preSum += temp.val;
map.put(preSum, temp);
temp = temp.next;
}
//第二次遍历链表
//再次计算前缀和, 这一次把其前缀和跟map中有重复的进行一个替换
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
temp = dummyNode;
preSum = 0;
while(temp != null){
preSum += temp.val;
if(map.containsKey(preSum)){
temp.next = map.get(preSum).next;
}
temp = temp.next;
}
return dummyNode.next;
}
}

浙公网安备 33010602011771号