Skip to main content

Remove Zero Sum Consecutive Nodes from Linked List - LeetCode Daily Challenge

Aakash Verma

Problem Statement

Given the head of a linked list, we repeatedly delete consecutive sequences of nodes that sum to 0 until there are no such sequences.

After doing so, return the head of the final linked list.  You may return any such answer.

 (Note that in the examples below, all sequences are serializations of ListNode objects.)

Example 1

Input: head = [1,2,-3,3,1]
Output: [3,1]
Note: The answer [1,2,1] would also be accepted.

Example 2

Input: head = [1,2,3,-3,4]
Output: [1,2,4]

Try here before watching the video.

Video Solution

Java Code

class Solution {
    public ListNode removeZeroSumSublists(ListNode head) {
        Map<Integer, ListNode> prefixSumMap = new HashMap<>();
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        prefixSumMap.put(0, dummy);
        ListNode ptr = head;
        int prefixSum = 0;
        
        while(ptr != null) {
            prefixSum += ptr.val;
            if(prefixSumMap.containsKey(prefixSum)) {
                ListNode prev = prefixSumMap.get(prefixSum);
                ListNode temp = prev.next;
                int sum = prefixSum;
                while(temp != ptr) {
                    sum += temp.val;
                    prefixSumMap.remove(sum);
                    temp = temp.next;
                }
                prev.next = ptr.next;
            } else {
                prefixSumMap.put(prefixSum, ptr);
            }
            ptr = ptr.next;
        }
        return dummy.next;
    }
}

C++ Code

class Solution {
public:
    ListNode* removeZeroSumSublists(ListNode* head) {
        unordered_map<int, ListNode*> prefixSumMap;
        ListNode* dummy = new ListNode(0);
        dummy->next = head;
        prefixSumMap[0] = dummy;
        ListNode* ptr = head;
        int prefixSum = 0;

        while (ptr != nullptr) {
            prefixSum += ptr->val;
            if (prefixSumMap.find(prefixSum) != prefixSumMap.end()) {
                ListNode* prev = prefixSumMap[prefixSum];
                ListNode* temp = prev->next;
                int sum = prefixSum;
                while (temp != ptr) {
                    sum += temp->val;
                    prefixSumMap.erase(sum);
                    temp = temp->next;
                }
                prev->next = ptr->next;
            } else {
                prefixSumMap[prefixSum] = ptr;
            }
            ptr = ptr->next;
        }
        return dummy->next;
    }
};

Python Code

class Solution:
    def removeZeroSumSublists(self, head: ListNode) -> ListNode:
        prefix_sum_map = dict()
        dummy = ListNode(0)
        dummy.next = head
        ptr = head
        prefix_sum = 0
        prefix_sum_map[0] = dummy

        while ptr:
            prefix_sum += ptr.val
            if prefix_sum in prefix_sum_map:
                prev = prefix_sum_map[prefix_sum]
                temp = prev.next
                _sum = prefix_sum
                while temp != ptr:
                    _sum += temp.val
                    del prefix_sum_map[_sum]
                    temp = temp.next
                prev.next = ptr.next
            else:
                prefix_sum_map[prefix_sum] = ptr
            ptr = ptr.next

        return dummy.next

Javascript Code

var removeZeroSumSublists = function(head) {
    let prefixSumMap = new Map();
    let dummy = new ListNode(0);
    dummy.next = head;
    prefixSumMap.set(0, dummy);
    let ptr = head;
    let prefixSum = 0;

    while (ptr !== null) {
        prefixSum += ptr.val;
        if (prefixSumMap.has(prefixSum)) {
            let prev = prefixSumMap.get(prefixSum);
            let temp = prev.next;
            let sum = prefixSum;
            while (temp !== ptr) {
                sum += temp.val;
                prefixSumMap.delete(sum);
                temp = temp.next;
            }
            prev.next = ptr.next;
        } else {
            prefixSumMap.set(prefixSum, ptr);
        }
        ptr = ptr.next;
    }
    return dummy.next;
};

Go Code

func removeZeroSumSublists(head *ListNode) *ListNode {
    prefixSumMap := make(map[int]*ListNode)
    dummy := &ListNode{Val: 0, Next: head}
    prefixSumMap[0] = dummy
    ptr := head
    prefixSum := 0

    for ptr != nil {
        prefixSum += ptr.Val
        if prev, ok := prefixSumMap[prefixSum]; ok {
            temp := prev.Next
            sum := prefixSum
            for temp != ptr {
                sum += temp.Val
                delete(prefixSumMap, sum)
                temp = temp.Next
            }
            prev.Next = ptr.Next
        } else {
            prefixSumMap[prefixSum] = ptr
        }
        ptr = ptr.Next
    }
    return dummy.Next
}

Complexity Analysis

Time Complexity: O(N), we are iterating through each node.
Space Complexity: O(N), in the worst-case scenario, all the numbers in the linked list might be positive and we may end up storing the N number of different sums in prefixSumMap.