DP ā 1D Problems (Fibonacci, Climbing Stairs, House Robber)
š Concept
1D DP problems have a single dimension: dp[i] depends on previous values dp[i-1], dp[i-2], etc.
Pattern recognition:
- dp[i] = f(dp[i-1]) ā linear dependency (can optimize to O(1) space)
- dp[i] = f(dp[i-1], dp[i-2]) ā two previous values (Fibonacci-like)
- dp[i] = f(dp[0...i-1]) ā all previous values (LIS pattern)
Top 1D DP problems for interviews:
- Fibonacci / Climbing Stairs ā dp[i] = dp[i-1] + dp[i-2]
- House Robber ā dp[i] = max(dp[i-1], dp[i-2] + nums[i])
- Coin Change ā dp[amount] = min(dp[amount-coin] + 1) for all coins
- Longest Increasing Subsequence ā dp[i] = max(dp[j] + 1) for j < i where a[j] < a[i]
- Word Break ā dp[i] = any dp[j] where s[j..i] is in dictionary
- Decode Ways ā dp[i] = dp[i-1] (valid single) + dp[i-2] (valid double)
Space optimization: If dp[i] only depends on the last k values, you only need k variables instead of an array. This reduces O(n) space to O(1).
š Real-world analogy: 1D DP is like climbing a staircase where each step's cost depends on which previous steps you took. You record the best cost to reach each step, building up to the top.
š» Code Example
1// COIN CHANGE ā Min coins to make amount2function coinChange(coins: number[], amount: number): number {3 const dp = new Array(amount + 1).fill(Infinity);4 dp[0] = 0;5 for (let i = 1; i <= amount; i++) {6 for (const coin of coins) {7 if (coin <= i && dp[i - coin] !== Infinity) {8 dp[i] = Math.min(dp[i], dp[i - coin] + 1);9 }10 }11 }12 return dp[amount] === Infinity ? -1 : dp[amount];13}1415// LONGEST INCREASING SUBSEQUENCE ā O(n²) DP16function lengthOfLIS(nums: number[]): number {17 const dp = new Array(nums.length).fill(1);18 for (let i = 1; i < nums.length; i++) {19 for (let j = 0; j < i; j++) {20 if (nums[j] < nums[i]) dp[i] = Math.max(dp[i], dp[j] + 1);21 }22 }23 return Math.max(...dp);24}2526// LIS ā O(n log n) with binary search27function lisOptimal(nums: number[]): number {28 const tails: number[] = [];29 for (const num of nums) {30 let lo = 0, hi = tails.length;31 while (lo < hi) {32 const mid = (lo + hi) >>> 1;33 if (tails[mid] < num) lo = mid + 1;34 else hi = mid;35 }36 tails[lo] = num;37 }38 return tails.length;39}4041// WORD BREAK42function wordBreak(s: string, wordDict: string[]): boolean {43 const words = new Set(wordDict);44 const dp = new Array(s.length + 1).fill(false);45 dp[0] = true;46 for (let i = 1; i <= s.length; i++) {47 for (let j = 0; j < i; j++) {48 if (dp[j] && words.has(s.substring(j, i))) {49 dp[i] = true;50 break;51 }52 }53 }54 return dp[s.length];55}5657// DECODE WAYS ā "226" ā "BZ"(2,26) or "VF"(22,6) or "BBF"(2,2,6)58function numDecodings(s: string): number {59 if (s[0] === '0') return 0;60 let prev2 = 1, prev1 = 1;61 for (let i = 1; i < s.length; i++) {62 let curr = 0;63 if (s[i] !== '0') curr += prev1;64 const twoDigit = parseInt(s.substring(i-1, i+1));65 if (twoDigit >= 10 && twoDigit <= 26) curr += prev2;66 prev2 = prev1;67 prev1 = curr;68 }69 return prev1;70}7172// MAXIMUM PRODUCT SUBARRAY73function maxProduct(nums: number[]): number {74 let maxProd = nums[0], minProd = nums[0], result = nums[0];75 for (let i = 1; i < nums.length; i++) {76 if (nums[i] < 0) [maxProd, minProd] = [minProd, maxProd];77 maxProd = Math.max(nums[i], maxProd * nums[i]);78 minProd = Math.min(nums[i], minProd * nums[i]);79 result = Math.max(result, maxProd);80 }81 return result;82}
šļø Practice Exercise
Practice Problems (Easy ā Hard):
- Coin change ā minimum coins to make amount
- Coin change II ā count ways to make amount
- Longest increasing subsequence
- Word break ā can string be segmented?
- Decode ways ā count valid decodings
- Maximum product subarray
- Perfect squares ā min number of squares that sum to n
- Palindrome partitioning II ā min cuts for palindrome substrings
- Jump game ā can you reach the end? (also solvable with greedy)
- Delete and earn ā maximize points from operations
ā ļø Common Mistakes
Not handling zero in decode ways ā '0' is invalid alone, but '10' and '20' are valid
Forgetting that LIS has both O(n²) and O(n log n) solutions ā interviewers often expect the faster one
Not tracking both max and min product in max product subarray ā negative Ć negative = positive
Initializing dp array with wrong values ā often should be 0, Infinity, or -Infinity depending on min/max
Not considering the coin change 'impossible' case ā return -1 if amount can't be made
š¼ Interview Questions
š¤ Mock Interview
Practice a live interview for DP ā 1D Problems (Fibonacci, Climbing Stairs, House Robber)