Try   HackMD

1171. Remove Zero Sum Consecutive Nodes from Linked List


My Solution

Solution 1:

The Key Idea for Solving This Coding Question

Brute force.

C++ Code

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode *removeZeroSumSublists(ListNode *head) { ListNode *dummy = new ListNode(), *prev = dummy; dummy->next = head; while (prev != nullptr) { int sum = 0; ListNode *left = prev->next, *right = prev->next; while (right != nullptr) { sum += right->val; if (sum == 0) { prev->next = right->next; //deleteNodes(left, right); left = prev->next; right = prev->next; } else { right = right->next; } } prev = prev->next; } head = dummy->next; delete dummy; return head; } private: void deleteNodes(ListNode *left, ListNode *right) { right->next = nullptr; ListNode *it = left; while (it != nullptr) { ListNode *x = it; it = it->next; delete x; } } };

Time Complexity

O(n2)
n
is the number of nodes in the linked list.

Space Complexity

O(1)

Solution 2:

The Key Idea for Solving This Coding Question

Prefix sum and hash table.

C++ Code 1 (One Pass)

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode *removeZeroSumSublists(ListNode *head) { ListNode *dummy = new ListNode(0), *curr = dummy; unordered_map<int, ListNode *> htbl; int prefixSum = 0; dummy->next = head; while (curr != nullptr) { prefixSum += curr->val; auto iter = htbl.find(prefixSum); if (iter == htbl.end()) { // No zero sum. htbl[prefixSum] = curr; curr = curr->next; } else { // Find zero sum. // The sum between iter->second->next to curr is zero. ListNode *x = iter->second->next; // Remove the consecutive nodes that sum to zero. iter->second->next = curr->next; curr = curr->next; // clear invalid records from htbl. int prefixTmp = prefixSum; while (true) { prefixTmp += x->val; if (prefixSum == prefixTmp) { break; } htbl.erase(prefixTmp); x = x->next; } } } head = dummy->next; delete dummy; return head; } };

Code 2 (Two Passes)

/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode *removeZeroSumSublists(ListNode *head) { unordered_map<int, ListNode *> htbl; int prefixSum = 0; ListNode *dummy = new ListNode(0); dummy->next = head; for (ListNode *it = dummy; it != nullptr; it = it->next) { prefixSum += it->val; htbl[prefixSum] = it; } prefixSum = 0; for (ListNode *it = dummy; it != nullptr; it = it->next) { prefixSum += it->val; it->next = htbl[prefixSum]->next; } head = dummy->next; delete dummy; return head; } };

Time Complexity

O(n)
n
is the number of nodes in the linked list.

Space Complexity

O(n)

Miscellaneous