-
Notifications
You must be signed in to change notification settings - Fork 0
/
range_addition.py
81 lines (63 loc) · 2.5 KB
/
range_addition.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/env python3
# Range Addition
#
# https://leetcode.com/problems/range-addition
#
# Assume you have an array of length n initialized with all 0's and are given k
# update operations.
#
# Each operation is represented as a triplet: [startIndex, endIndex, inc] which
# increments each element of subarray A[startIndex ... endIndex] (startIndex and
# endIndex inclusive) with inc.
#
# Return the modified array after all k operations were executed.
from typing import List
def test():
"""
Run `pytest <this-file>`.
"""
def test_algo(algo):
assert algo(length=5, updates=[[1, 3, 2], [2, 4, 3], [0, 2, -2]]) == [
-2,
0,
3,
5,
3,
]
# Test all different algorithms/implementations
solution = Solution()
for algo in [solution.brute_force, solution.optimized]:
test_algo(algo)
class Solution:
def brute_force(self, length: int, updates: List[List[int]]):
"""
Approach: Brute-force.
Idea: Apply each update all affected indices in the output array directly.
Time: O(m*n): Given an output array length of n and m updates, in the worst case each update requires incrementing all n elements in the array.
Space: O(1): No additional memory is used.
Leetcode: ? ms runtime, ? MB memory
"""
arr = [0] * length
for start_idx, end_idx, inc in updates:
for i in range(start_idx, end_idx + 1):
arr[i] += inc
return arr
def optimized(self, length: int, updates: List[List[int]]):
"""
Approach: Store increment diff.
Idea: Only save the idx at which an increment was introduced and when it was undone again.
Time: O(m+n): Given an output array length of n and m updates, exctracting increment introduction and removal indices takes O(m) overall, and then we can simply do one pass over output array and apply increment introductions and removals as we go (O(n)).
Space: O(m): For each update, we store the diff to be applied when that idx is reached.
Leetcode: ? ms runtime, ? MB memory
"""
diff = [0] * length
for start_idx, end_idx, inc in updates:
diff[start_idx] += inc
if end_idx + 1 < length:
diff[end_idx + 1] -= inc
arr = [0] * length
diff_sum = 0
for i in range(0, length):
diff_sum += diff[i]
arr[i] = diff_sum
return arr