Top 10 Dynamic Programming Questions
Top 10 Dynamic Programming Questions
The dynamic programming approach optimizes the House Robber problem by considering two scenarios at each house: robbing it or skipping it. The principle of 'no two adjacent houses' allows the use of a dp array where dp[i] is the maximum amount of money that can be robbed up to the i-th house, calculated with dp[i] = max(nums[i-1] + dp[i-2], dp[i-1]). This ensures subproblems are solved optimally and reused, reducing unnecessary computations .
In the Unique Paths problem, backtracking is avoided by using a dp array where each cell dp[i][j] stores the number of unique paths to that cell. The value is computed as dp[i][j] = dp[i-1][j] + dp[i][j-1], meaning it builds upon previously computed values instead of re-evaluating routes. This ensures the solution is derived in O(m*n) time without backtracking through potential paths .
The Sliding Window Maximum problem is efficiently solved using a deque to maintain indices of the maximum elements within the current window. The solution involves storing indices in a deque such that the largest one is always at the front. As the window slides, indices out of the window's range are removed from the front. This method ensures the operations within each window move are done in constant time, hence achieving an overall time complexity of O(n).
In the Subset Sum problem, the dynamic programming matrix is initialized such that its first column is set to 'true', meaning a zero sum can always be achieved with any elements, including none. The matrix is updated such that dp[i][j] is 'true' if the sum j can be achieved using the first i numbers by either including the current number or not .
Dynamic programming solves the Rod Cutting problem by storing the results of subproblems to avoid redundant calculations, providing an efficient optimization over the exponential time complexity of a naive recursive approach. The primary advantage is that it reduces the time complexity from exponential to polynomial, specifically O(n^2), where n is the length of the rod. This is achieved by maintaining a dp array where dp[i] holds the maximum profit for a rod of length i .
In the Min Path Sum problem, the dp array holds the minimum path sums up to each cell, initialized with the top-left cell as the starting point. The array is updated such that dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j], allowing each cell to be evaluated based on the minimum path sum reaching it. This provides an optimal solution with time complexity O(n*m) for an n by m grid .
Dynamic programming effectively optimizes the Longest Valid Subsequence problem by decomposing it into subproblems and using a dp array where dp[i] tracks the longest valid subsequence ending with the i-th character. Each character is evaluated against its prior subsequences to update the dp array with maximal length. This avoids redundant checks present in recursive methods, leading to a substantial reduction in time complexity, typically down to polynomial time for practical inputs .
The two-pointer technique for the Tapping Rain Water problem uses the principle of focusing on the smaller of two boundaries to determine the water trapped. By maintaining two pointers from the extremes moving inward, the approach ensures each step leads to a decision based on the lowest height boundary, effectively calculating and accumulating trapped water. This technique is effective as it operates in O(n) time complexity without needing extra space for auxiliary arrays .
In the Longest Common Subsequence problem solved via dynamic programming, the state dp[i][j] represents the length of LCS for the strings s1 (up to i) and s2 (up to j). This state depends on the previous states: if the characters s1[i-1] and s2[j-1] match, then dp[i][j] = dp[i-1][j-1] + 1; otherwise, dp[i][j] = max(dp[i-1][j], dp[i][j-1]). This ensures the state builds upon and optimizes solutions to subproblems .
In the Jump Game problem, the greedy strategy involves iterating through the array and maintaining the farthest position that can be reached, updated as far = max(far, i + nums[i]) for each index i. If the current index exceeds the farthest reached, it indicates a gap, meaning the end cannot be reached. If at any step, this farthest position reaches or exceeds the last index, the solution is true, indicating a path to the end is possible .