You claim you've implemented a dynamic programming solution, but I'm afraid your attempt has actually made your code slower.
Your code:
T = ['inf' for _ in range(len(nums))]
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
if j == i:
T[i] = nums[i]
if T[i] == k:
count +=1
else:
currSum = T[j-1] + nums[j]
T[j] = currSum
if currSum == k:
count +=1
For the first change, let's replace the T[i]
and nums[i]
indices in the j == i
case with [j]
. Obviously, the code should be equivalent.
T = ['inf' for _ in range(len(nums))]
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
if j == i:
T[j] = nums[j]
if T[j] == k:
count +=1
else:
currSum = T[j-1] + nums[j]
T[j] = currSum
if currSum == k:
count +=1
Let's add currSum
to the if
clause as well, and rearrange things to look a
little more like the else:
clause.
T = ['inf' for _ in range(len(nums))]
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
if j == i:
currSum = nums[j]
T[j] = currSum
if currSum == k:
count +=1
else:
currSum = T[j-1] + nums[j]
T[j] = currSum
if currSum == k:
count +=1
Now we can see we can pull the if currSum == k:
test out of the if...else
clause.
T = ['inf' for _ in range(len(nums))]
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
if j == i:
currSum = nums[j]
T[j] = currSum
else:
currSum = T[j-1] + nums[j]
T[j] = currSum
if currSum == k:
count += 1
On the second and subsequent iterations of the inner loop, we add a number to
T[j-1]
. On the previous iteration, you stored currSum
into that location.
So, we can replace T[j-1]
with currSum
from the previous iteration.
T = ['inf' for _ in range(len(nums))]
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
if j == i:
currSum = nums[j]
T[j] = currSum
else:
currSum = currSum + nums[j]
T[j] = currSum
if currSum == k:
count += 1
At this point, you are storing into T[j]
but never loading values from T[]
,
so the entire T
array can be deleted.
count = 0
for i in range(len(nums)):
for j in range(i,len(nums)):
if j == i:
currSum = nums[j]
else:
currSum = currSum + nums[j]
if currSum == k:
count += 1
Finally, we can remove the first if
statement by realizing it is just priming the accumulator currSum
with 0 + nums[j]
on the first iteration:
count = 0
for i in range(len(nums)):
currSum = 0
for j in range(i, len(nums)):
currSum += nums[j]
if currSum == k:
count += 1
At this point, you can see your "dynamic programming" attempt was just busy work,
and didn't actually improve your algorithm at all. In fact, it actually slowed it
down and increased memory usage for no gain.
I have not changed your algorithm, just improved your implementation of the
algorithm by removing the busy work. It is was and still is sequentially
adding the numbers in range defined by a double for loop, so it still \$O(n^2)\$.
There is an improved algorithm which would use something like your T[]
array.
But this is a code-review, not an algorithm review, so I shan't spoil your fun of
trying to find it.