Python | Prefix Sum Subarray till False value

The prefix array is quite famous in the programming practice. This article would discuss a variation of this scheme. This deals with the cumulative list sum till a False value, and again starts cumulation from the occurrence of True value. Let’s discuss certain ways in which this can be performed.

Method #1 : Using Naive Method In the naive method, we just construct the new list comprising of the summation of prev. value of list until 0 and restarts the procedure once a non-zero value is encountered.

Python3

 `# Python3 code to demonstrate ``# Prefix Sum Subarray till False value ``# using naive method ` `# initializing list of lists``test_list ``=` `[``1``, ``3``, ``4``, ``0``, ``4``, ``5``, ``0``, ``7``, ``8``]` `# printing original list``print` `("The original ``list` `is` `: " ``+` `str``(test_list))` `# Prefix Sum Subarray till False value ``# using naive method``for` `i ``in` `range``(``1``, ``len``(test_list)):``    ``if` `test_list[i]:  ``        ``test_list[i] ``+``=` `test_list[i ``-` `1``]` `# printing result``print` `("The computed modified new ``list` `: " ``+` `str``(test_list))`

Output:
```The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [1, 4, 8, 0, 4, 9, 0, 7, 15]```

Time Complexity: O(n), where n is the length of the list test_list
Auxiliary Space: O(n) additional space of size n is created where n is the number of elements in the res list

Method #2 : Using from_iterable() + accumulate() + groupby() The above three functions combine together to perform this particular task. In this, the accumulate function performs the task of addition of elements, groupby function groups the non-zero values and the result is combined by the from_iterable function.

Python3

 `# Python3 code to demonstrate ``# Prefix Sum Subarray till False value ``# from_iterable() + accumulate() + groupby()``from` `itertools ``import` `groupby, accumulate, chain` `# initializing list of lists``test_list ``=` `[``1``, ``3``, ``4``, ``0``, ``4``, ``5``, ``0``, ``7``, ``8``]` `# printing original list``print` `("The original ``list` `is` `: " ``+` `str``(test_list))` `# Prefix Sum Subarray till False value ``# from_iterable() + accumulate() + groupby()``res ``=` `list``(chain.from_iterable(accumulate(j) ``            ``for` `i, j ``in` `groupby(test_list, ``bool``)))` `# printing result``print` `("The computed modified new ``list` `: " ``+` `str``(res))`

Output:
```The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [1, 4, 8, 0, 4, 9, 0, 7, 15]```

Method #3: Using list comprehension

Algorithm:

1. Initialize the input list test_list.
2. Print the original list.
3. Compute the modified list using list comprehension:
4. For each element test_list[i] starting from index 1 up to the end of the list, if the element is True (i.e., non zero), add the value of the previous element test_list[i-1] to the current element test_list[i]. Otherwise, leave the element unchanged.
5. Print the computed modified list.

Python3

 `# initializing list of lists``test_list ``=` `[``1``, ``3``, ``4``, ``0``, ``4``, ``5``, ``0``, ``7``, ``8``]` `# printing original list``print``(``"The original list is : "` `+` `str``(test_list))` `# Prefix Sum Subarray till False value using list comprehension``test_list ``=` `[test_list[i] ``+` `test_list[i``-``1``] ``if` `test_list[i] ``else` `test_list[i] ``for` `i ``in` `range``(``1``, ``len``(test_list))]` `# printing result``print``(``"The computed modified new list : "` `+` `str``(test_list))``#This code is contributed by Vinay Pinjala.`

Output
```The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [4, 7, 0, 4, 9, 0, 7, 15]```

The time complexity of this algorithm is O(N), where N is the length of the input list test_list. This is because we iterate through each element in the list once to compute the modified list using list comprehension.
Space Complexity:

The auxiliary space of this algorithm is O(N), where N is the length of the input list test_list. This is because we create a new list to store the modified list, which has the same length as the input list. Note that the space complexity could be reduced to O(1) by modifying the input list in place instead of creating a new list, but this would change the original input list.

Method 4: Using map function with lambda expression.

Algorithm:

1. Create a new list prefix_sum and initialize it with the first element as 0, and the remaining elements as the original list.
2. Apply map function on a lambda function to iterate over the range 1 to length of prefix_sum.
3. For each iteration, check if the current element is not equal to 0, then add the previous element of prefix_sum to the current element of prefix_sum and update it in the test_list.
4. Return the modified test_list by slicing from the second element to the end of the list.

Python3

 `test_list ``=` `[``1``, ``3``, ``4``, ``0``, ``4``, ``5``, ``0``, ``7``, ``8``]``prefix_sum ``=` `[``0``] ``+` `test_list``print``(``"The original list is : "` `+` `str``(test_list))` `test_list ``=` `list``(``map``(``lambda` `i: prefix_sum[i] ``+` `prefix_sum[i``-``1``] ``if` `prefix_sum[i] ``else` `prefix_sum[i], ``range``(``1``, ``len``(prefix_sum))))``print``(``"The computed modified new list : "` `+` `str``(test_list[``1``:]))`

Output
```The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list : [4, 7, 0, 4, 9, 0, 7, 15]```

Time Complexity: O(n)

The time complexity of creating prefix_sum list and map function is O(n).
The lambda function executes n-1 times, so its time complexity is O(1) for each execution.
Therefore, the overall time complexity is O(n).
Auxiliary Space: O(n) We use an additional prefix_sum list, which has the same size as the original list.
Therefore, the space complexity is O(n).

Method 5: Using heapq:

Algorithm:

1. Initialize a heap with a tuple (0, -1), where 0 is the prefix sum of the subarray ending at index -1.
2. Initialize a list res with zeros of the same length as test_list.
3. Traverse the list test_list with index i and value x.
4. If x is non-zero, pop the smallest element (s, j) from the heap and set res[i] to s + x. Push (s + x, j) back to the heap.
5. If x is zero, push (0, i) to the heap.
6. The list res is the computed modified new list.

Python3

 `import` `heapq` `# initializing list of lists``test_list ``=` `[``1``, ``3``, ``4``, ``0``, ``4``, ``5``, ``0``, ``7``, ``8``]` `# printing original list``print``(``"The original list is : "` `+` `str``(test_list))` `# Prefix Sum Subarray till False value using heapq method``heap ``=` `[(``0``, ``-``1``)]``res ``=` `[``0``] ``*` `len``(test_list)` `for` `i, x ``in` `enumerate``(test_list):``    ``if` `x:``        ``s, j ``=` `heapq.heappop(heap)``        ``res[i] ``=` `s ``+` `x``        ``heapq.heappush(heap, (s ``+` `x, j))``    ``else``:``        ``heapq.heappush(heap, (``0``, i))` `# printing result``print``(``"The computed modified new list using heapq method: "` `+` `str``(res))``#This code is contributed by Jyothi pinjala.`

Output
```The original list is : [1, 3, 4, 0, 4, 5, 0, 7, 8]
The computed modified new list using heapq method: [1, 4, 8, 0, 4, 9, 0, 7, 15]```

Time complexity:
The time complexity of the algorithm is O(n*log n), where n is the length of the input list test_list. The loop traverses the input list once, and for each non-zero value, a heap operation is performed which takes O(log n) time.

Space complexity:
The space complexity of the algorithm is O(n), where n is the length of the input list test_list. The heap can contain at most n elements, and the list res has length n.

Previous
Next