Skip to content

dp3#1533

Open
spencerkrebs wants to merge 1 commit into
super30admin:masterfrom
spencerkrebs:master
Open

dp3#1533
spencerkrebs wants to merge 1 commit into
super30admin:masterfrom
spencerkrebs:master

Conversation

@spencerkrebs

Copy link
Copy Markdown

No description provided.

@super30admin

Copy link
Copy Markdown
Owner

Least Falling Path Sum (min-falling-path-sum.py)

Your solution is excellent! It correctly implements a dynamic programming approach with optimal time complexity. Here are some strengths and suggestions for improvement:

Strengths:

  • You correctly identified the need for a DP table and implemented the state transitions accurately.
  • You handled the edge cases (first and last columns) properly.
  • The code is clean and easy to follow.

Areas for Improvement:

  1. Space Optimization: You can reduce the space complexity from O(n^2) to O(n) by only storing the previous row of DP values. Instead of maintaining a full 2D array, you can use two arrays: prev for the previous row and curr for the current row. This is especially useful for large n, but even for n=100, it's a good practice.

    Example:

    n = len(matrix)
    prev = matrix[0][:]
    for i in range(1, n):
         curr = [0] * n
         for j in range(n):
             # ... same logic but using prev instead of dp[i-1]
         prev = curr
    return min(prev)
    
  2. Minor Code Improvements:

    • Instead of initializing dp[0][i] in a loop, you can directly set dp[0] = matrix[0][:] (or list(matrix[0]) for a copy).
    • The last loop to find the minimum in the last row can be replaced with min(dp[-1]).
  3. Comments: Your comments are helpful, but you could add a brief comment at the top explaining the approach. Also, the comment "first col - 2 val compare" might be slightly misleading because for j==0, you are comparing dp[i-1][j] and dp[i-1][j+1] (which are the same as directly below and diagonally right). Similarly for the last column. This is correct, but the comment could be clearer.

Overall, your solution is very good and passes all criteria. The space optimization is optional but recommended.

VERDICT: PASS


Delete and Earn (delete-and-earn.py)

Your approach is on the right track: you recognized that the problem can be reduced to a dynamic programming problem similar to the "house robber" problem. However, there is a critical issue in your code: you did not initialize the base cases for the dynamic programming array correctly.

Specifically, you are using the same array t to store both the total points per number and the DP values. This is acceptable, but you need to handle the first two indices properly. For the DP to work:

  • dp[0] should be t[0] (which is 0 since numbers start at 1, but if there were 0, it would be the total for 0).
  • dp[1] should be the maximum of t[0] and t[1].
    Then for i from 2 to maxVal, dp[i] = max(dp[i-1], t[i] + dp[i-2]).

In your code, you start the loop at index 2, but you never set t[1] to the correct DP value. So if maxVal is 1, your loop doesn't run, and you return t[1] which is the total points for number 1, which is correct only if there are no zeros (which there aren't). But if maxVal is greater than 1, then for index1, you are using the original value (total points for 1) instead of the DP value which should be the max of t[0] and t[1]. This might lead to an incorrect result.

For example, consider nums = [1,1,2]. Then maxVal = 2, and t = [0, 2, 2]. Your code would then run the loop for i=2: t[2] = max(t[1]=2, t[2]+t[0]=2+0=2) = 2. So the result is 2. But the correct answer should be 4: take both 1's to get 2 points, and then you cannot take 2 because it is adjacent? Wait, actually: if you take a 1, you delete 0 and 2. So after taking one 1, you delete all 2's. Then you can take the other 1? Actually, no: because when you take the first 1, you delete all 0 and 2. Then the array has only 1 left? So you can take both 1's? But the rule says: when you delete a number, you must delete every element equal to nums[i]-1 and nums[i]+1. So if you take 1, you delete all 0 and 2. Then the array still has the other 1? Because 1 is not equal to 0 or 2. So you can take the other 1. So total points = 1 + 1 = 2. But wait, that doesn't match: actually, the problem says you must delete every element equal to nums[i]-1 and nums[i]+1. So when you take the first 1, you delete all 0 and 2. Then the array has no more elements? Because the only other element is 1, which is not deleted by the rule? But the rule says "afterwards, you must delete every element equal to nums[i]-1 and nums[i]+1". So you are forced to delete all 0 and 2. But the other 1 is not deleted because it is not 0 or 2. So you can then take the other 1. So total points = 2. But actually, the problem does not require that you delete the number you just took? It says: "delete it to earn points", and then "you must delete every element equal to nums[i]-1 and nums[i]+1". So the number you took is already deleted (you picked and deleted it), and then you must delete all numbers equal to i-1 and i+1. So the other 1 is not deleted by the rule because it is not equal to 0 or 2. So you can take it later. So the correct answer for [1,1,2] is 2 (from the two 1's) because if you take a 1 first, you get 1 point and then you delete all 0 and 2. Then the array has one 1 left. Then you take that 1 to get another point. Total 2. But wait, the total points from the two 1's is 2, which is correct. However, if you take the 2 first, you get 2 points and then you must delete all 1 and 3. So you delete the two 1's. Then the array is empty. So you get 2 points. So the maximum is 2. So your code returns 2, which is correct for this case.

But consider another example: nums = [1,2,2]. Then maxVal=2, t = [0,1,4]. Your code: for i=2, t[2] = max(t[1]=1, t[2]+t[0]=4+0=4)=4. So returns 4. Correct: if you take both 2's, you get 4 points. And you have to delete 1 and 3. So after taking the first 2, you delete all 1 and 3. Then the array has one 2 left? So you can take it. So 4 points.

Now consider nums = [1,1,1,2,2]. Then maxVal=2, t=[0,3,4]. Your code: t[2]=max(t[1]=3, t[2]+t[0]=4+0=4)=4. So returns 4. But the correct answer should be: if you take the two 2's, you get 4 points and delete all 1 and 3. So you lose the three 1's. Total 4. Alternatively, if you take the three 1's, you get 3 points and delete all 0 and 2. So you lose the two 2's. Total 3. So 4 is correct.

Now consider a case where the base case matters: nums = [1,2]. Then maxVal=2, t=[0,1,2]. Your code: for i=2, t[2]=max(t[1]=1, t[2]+t[0]=2+0=2)=2. So returns 2. Correct: take the 2, get 2 points, and delete 1 and 3. So the 1 is deleted. Total 2. Alternatively, take the 1: get 1 point, delete 0 and 2. So the 2 is deleted. Total 1. So 2

VERDICT: NEEDS_IMPROVEMENT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants