└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # 1.7k upvotes. 31.2k views. 154 comments 2 | 3 |

4 | 5 | Before starting the topic let me introduce myself. I am a Mobile Developer currently working in Warsaw and spending my free time for interview preparations. I started to prepare for interviews two years ago. At that time I should say I could not solve the two sum problem. Easy problems seemed to me like hard ones so most of the time I had to look at editorials and discuss section. Currently, I have solved ~800 problems and time to time participate in contests. I usually solve 3 problems in a contest and sometimes 4 problems. Ok, lets come back to the topic. 6 | 7 | Recently I have concentrated my attention on Dynamic Programming cause its one of the hardest topics in an interview prep. After solving ~140 problems in DP I have noticed that there are few patterns that can be found in different problems. So I did a research on that and find the following topics. I will not give complete ways how to solve problems but these patterns may be helpful in solving DP. 8 | 9 | # Patterns 10 | --- 11 | 12 | [Minimum (Maximum) Path to Reach a Target](#Minimum-(Maximum)-Path-to-Reach-a-Target) 13 | [Distinct Ways](#distinct-ways) 14 | [Merging Intervals](#Merging-Intervals) 15 | [DP on Strings](#DP-on-Strings) 16 | [Decision Making](#Decision-Making) 17 | 18 | # Minimum (Maximum) Path to Reach a Target 19 | --- 20 | 21 | Generate problem statement for this pattern 22 | 23 | ### Statement 24 | > Given a target find minimum (maximum) cost / path / sum to reach the target. 25 | 26 | ### Approach 27 | 28 | > Choose minimum (maximum) path among all possible paths before the current state, then add value for the current state. 29 | 30 | ```cpp 31 | routes[i] = min(routes[i-1], routes[i-2], ... , routes[i-k]) + cost[i] 32 | ``` 33 | 34 | Generate optimal solutions for all values in the target and return the value for the target. 35 | 36 | ```cpp 37 | for (int i = 1; i <= target; ++i) { 38 | for (int j = 0; j < ways.size(); ++j) { 39 | if (ways[j] <= i) { 40 | dp[i] = min(dp[j], dp[i - ways[j]]) + cost / path / sum; 41 | } 42 | } 43 | } 44 | 45 | return dp[target] 46 | ``` 47 | ### Similar Problems 48 | 49 | [746. Min Cost Climbing Stairs](https://leetcode.com/problems/min-cost-climbing-stairs/) `Easy` 50 | 51 | ```cpp 52 | for (int i = 2; i <= n; ++i) { 53 | dp[i] = min(dp[i-1], dp[i-2]) + (i == n ? 0 : cost[i]); 54 | } 55 | 56 | return dp[n] 57 | ``` 58 | 59 | [64. Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/) `Medium` 60 | 61 | ```cpp 62 | for (int i = 1; i < n; ++i) { 63 | for (int j = 1; j < m; ++j) { 64 | grid[i][j] = min(grid[i-1][j], grid[i][j-1]) + grid[i][j]; 65 | } 66 | } 67 | 68 | return grid[n-1][m-1] 69 | ``` 70 | 71 | [322. Coin Change](https://leetcode.com/problems/coin-change/) `Medium` 72 | 73 | ```cpp 74 | for (int j = 1; j <= amount; ++j) { 75 | for (int i = 0; i < coins.size(); ++i) { 76 | if (coins[i] <= j) { 77 | dp[j] = min(dp[j], dp[j - coins[i]] + 1); 78 | } 79 | } 80 | } 81 | ``` 82 | 83 | [931. Minimum Falling Path Sum](https://leetcode.com/problems/minimum-falling-path-sum/) `Medium` 84 | 85 | [983. Minimum Cost For Tickets](https://leetcode.com/problems/minimum-cost-for-tickets/) `Medium` 86 | 87 | [650. 2 Keys Keyboard](https://leetcode.com/problems/2-keys-keyboard/) `Medium` 88 | 89 | [279. Perfect Squares](https://leetcode.com/problems/perfect-squares/) `Medium` 90 | 91 | [1049. Last Stone Weight II](https://leetcode.com/problems/last-stone-weight-ii/) `Medium` 92 | 93 | [120. Triangle](https://leetcode.com/problems/triangle/) `Medium` 94 | 95 | [474. Ones and Zeroes](https://leetcode.com/problems/ones-and-zeroes/) `Medium` 96 | 97 | [221. Maximal Square](https://leetcode.com/problems/maximal-square/) `Medium` 98 | 99 | [322. Coin Change](https://leetcode.com/problems/coin-change/) `Medium` 100 | 101 | [1240. Tiling a Rectangle with the Fewest Squares](https://leetcode.com/problems/tiling-a-rectangle-with-the-fewest-squares/) `Hard` 102 | 103 | [174. Dungeon Game](https://leetcode.com/problems/dungeon-game/) `Hard` 104 | 105 | [871. Minimum Number of Refueling Stops](https://leetcode.com/problems/minimum-number-of-refueling-stops/) `Hard` 106 | 107 | # Distinct Ways 108 | --- 109 | 110 | Generate problem statement for this pattern 111 | 112 | ### Statement 113 | > Given a target find a number of distinct ways to reach the target. 114 | 115 | ### Approach 116 | 117 | > Sum all possible ways to reach the current state. 118 | 119 | ```cpp 120 | routes[i] = routes[i-1] + routes[i-2], ... , + routes[i-k] 121 | ``` 122 | 123 | Generate sum for all values in the target and return the value for the target. 124 | 125 | ```cpp 126 | for (int i = 1; i <= target; ++i) { 127 | for (int j = 0; j < ways.size(); ++j) { 128 | if (ways[j] <= i) { 129 | dp[j] += dp[i - ways[j]]; 130 | } 131 | } 132 | } 133 | 134 | return dp[target] 135 | ``` 136 | 137 | ### Similar Problems 138 | 139 | [70. Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) `easy` 140 | 141 | ```cpp 142 | for (int stair = 2; stair <= n; ++stair) { 143 | for (int step = 1; step <= 2; ++step) { 144 | dp[stair] += dp[stair-step]; 145 | } 146 | } 147 | ``` 148 | 149 | [62. Unique Paths](https://leetcode.com/problems/unique-paths/) `Medium` 150 | 151 | ```cpp 152 | for (int i = 1; i < m; ++i) { 153 | for (int j = 1; j < n; ++j) { 154 | dp[i][j] = dp[i][j-1] + dp[i-1][j]; 155 | } 156 | } 157 | ``` 158 | 159 | [1155. Number of Dice Rolls With Target Sum](https://leetcode.com/problems/number-of-dice-rolls-with-target-sum/) `Medium` 160 | 161 | ```cpp 162 | for (int rep = 1; rep <= d; ++rep) { 163 | vector new_ways(target+1); 164 | for (int already = 0; already <= target; ++already) { 165 | for (int pipe = 1; pipe <= f; ++pipe) { 166 | if (already - pipe >= 0) { 167 | new_ways[already] += ways[already - pipe]; 168 | new_ways[already] %= mod; 169 | } 170 | } 171 | } 172 | ways = new_ways; 173 | } 174 | ``` 175 | 176 | **Note** 177 | 178 | Some questions point out the number of repetitions, in that case, add one more loop to simulate every repetition. 179 | 180 | [688. Knight Probability in Chessboard](https://leetcode.com/problems/knight-probability-in-chessboard/) `Medium` 181 | 182 | [494. Target Sum](https://leetcode.com/problems/target-sum/) `Medium` 183 | 184 | [377. Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/) `Medium` 185 | 186 | [935. Knight Dialer](https://leetcode.com/problems/knight-dialer/) `Medium` 187 | 188 | [1223. Dice Roll Simulation](https://leetcode.com/problems/dice-roll-simulation/) `Medium` 189 | 190 | [416. Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/) `Medium` 191 | 192 | [808. Soup Servings](https://leetcode.com/problems/soup-servings/) `Medium` 193 | 194 | [790. Domino and Tromino Tiling](https://leetcode.com/problems/domino-and-tromino-tiling/) `Medium` 195 | 196 | [801. Minimum Swaps To Make Sequences Increasing](https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/) 197 | 198 | [673. Number of Longest Increasing Subsequence](https://leetcode.com/problems/number-of-longest-increasing-subsequence/) `Medium` 199 | 200 | [63. Unique Paths II](https://leetcode.com/problems/unique-paths-ii/) `Medium` 201 | 202 | [576. Out of Boundary Paths](https://leetcode.com/problems/out-of-boundary-paths/) `Medium` 203 | 204 | [1269. Number of Ways to Stay in the Same Place After Some Steps](https://leetcode.com/problems/number-of-ways-to-stay-in-the-same-place-after-some-steps/) `Hard` 205 | 206 | [1220. Count Vowels Permutation](https://leetcode.com/problems/count-vowels-permutation/) `Hard` 207 | 208 | # Merging Intervals 209 | --- 210 | 211 | Generate problem statement for this pattern 212 | 213 | ### Statement 214 | > Given a set of numbers find an optimal solution for a problem considering the current number and the best you can get from the left and right sides. 215 | 216 | ### Approach 217 | 218 | > Find all optimal solutions for every interval and return the best possible answer. 219 | 220 | ```cpp 221 | // from i to j 222 | dp[i][j] = dp[i][k] + result[k] + dp[k+1][j] 223 | ``` 224 | 225 | Get the best from the left and right sides and add a solution for the current position. 226 | 227 | ```cpp 228 | for(int l = 1; l Given two strings `s1` and `s2`, return `some result`. 274 | 275 | ### Approach 276 | 277 | > Most of the problems on this pattern requires a solution that can be accepted in O(n^2) complexity. 278 | 279 | ```cpp 280 | // i - indexing string s1 281 | // j - indexing string s2 282 | for (int i = 1; i <= n; ++i) { 283 | for (int j = 1; j <= m; ++j) { 284 | if (s1[i-1] == s2[j-1]) { 285 | dp[i][j] = /*code*/; 286 | } else { 287 | dp[i][j] = /*code*/; 288 | } 289 | } 290 | } 291 | ``` 292 | 293 | > If you are given one string `s` the approach may little vary 294 | 295 | ```cpp 296 | for (int l = 1; l < n; ++l) { 297 | for (int i = 0; i < n-l; ++i) { 298 | int j = i + l; 299 | if (s[i] == s[j]) { 300 | dp[i][j] = /*code*/; 301 | } else { 302 | dp[i][j] = /*code*/; 303 | } 304 | } 305 | } 306 | ``` 307 | 308 | [1143. Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) `Medium` 309 | 310 | ```cpp 311 | for (int i = 1; i <= n; ++i) { 312 | for (int j = 1; j <= m; ++j) { 313 | if (text1[i-1] == text2[j-1]) { 314 | dp[i][j] = dp[i-1][j-1] + 1; 315 | } else { 316 | dp[i][j] = max(dp[i-1][j], dp[i][j-1]); 317 | } 318 | } 319 | } 320 | ``` 321 | 322 | [647. Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) `Medium` 323 | 324 | ```cpp 325 | for (int l = 1; l < n; ++l) { 326 | for (int i = 0; i < n-l; ++i) { 327 | int j = i + l; 328 | if (s[i] == s[j] && dp[i+1][j-1] == j-i-1) { 329 | dp[i][j] = dp[i+1][j-1] + 2; 330 | } else { 331 | dp[i][j] = 0; 332 | } 333 | } 334 | } 335 | ``` 336 | 337 | [516. Longest Palindromic Subsequence](https://leetcode.com/problems/longest-palindromic-subsequence/) `Medium` 338 | 339 | [1092. Shortest Common Supersequence](https://leetcode.com/problems/shortest-common-supersequence/) `Medium` 340 | 341 | [72. Edit Distance](https://leetcode.com/problems/edit-distance/) `Hard` 342 | 343 | [115. Distinct Subsequences](https://leetcode.com/problems/distinct-subsequences/) `Hard` 344 | 345 | [712. Minimum ASCII Delete Sum for Two Strings](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/) `Medium` 346 | 347 | [5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) `Medium` 348 | 349 | # Decision Making 350 | --- 351 | 352 | The general problem statement for this pattern is forgiven situation decide whether to use or not to use the current state. So, the problem requires you to make a decision at a current state. 353 | 354 | ### Statement 355 | > Given a set of values find an answer with an option to choose or ignore the current value. 356 | 357 | ### Approach 358 | 359 | > If you decide to choose the current value use the previous result where the value was ignored; vice-versa, if you decide to ignore the current value use previous result where value was used. 360 | 361 | ```cpp 362 | // i - indexing a set of values 363 | // j - options to ignore j values 364 | for (int i = 1; i < n; ++i) { 365 | for (int j = 1; j <= k; ++j) { 366 | dp[i][j] = max({dp[i][j], dp[i-1][j] + arr[i], dp[i-1][j-1]}); 367 | dp[i][j-1] = max({dp[i][j-1], dp[i-1][j-1] + arr[i], arr[i]}); 368 | } 369 | } 370 | ``` 371 | 372 | [198. House Robber](https://leetcode.com/problems/house-robber/) `Easy` 373 | 374 | ```cpp 375 | for (int i = 1; i < n; ++i) { 376 | dp[i][1] = max(dp[i-1][0] + nums[i], dp[i-1][1]); 377 | dp[i][0] = dp[i-1][1]; 378 | } 379 | ``` 380 | 381 | [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) `Easy` 382 | 383 | [714. Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) `Medium` 384 | 385 | [309. Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) `Medium` 386 | 387 | [123. Best Time to Buy and Sell Stock III](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) `Hard` 388 | 389 | [188. Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) `Hard` 390 | 391 | I hope these tips will be helpful 😊 392 | 393 | Follow me for more updates on [Twitter](https://twitter.com/aatalyk) 394 | 395 | # Comments 396 | 397 | ![alt text](https://i.ibb.co/fFVfsS3/Screen-Shot-2020-01-08-at-16-45-23.png "Logo Title Text 1") 398 | ![alt text](https://i.ibb.co/JBnHnZb/Screen-Shot-2020-01-08-at-16-45-17.png "Logo Title Text 1") 399 | ![alt text](https://i.ibb.co/RQVv4jq/Screen-Shot-2020-01-08-at-16-44-14.png "Logo Title Text 1") 400 | --------------------------------------------------------------------------------