Patterns
Patterns
Generate optimal solutions for all values in the target and return the value for the target.
Top-Down
for (int j = 0; j < ways.size(); ++j) {
Bottom-Up
for (int i = 1; i <= target; ++i) {
if (ways[j] <= i) {
return dp[target]
Top-Down
int result = min(minCost(n-1, cost, memo), minCost(n-2, cost, memo)) + (n == cost.size() ? 0 : cost[n]);
Bottom-Up
for (int i = 2; i <= n; ++i) {
return dp[n]
Top-Down
int result = min(pathSum(i+1, j, grid, memo), pathSum(i, j+1, grid, memo)) + grid[i][j];
return grid[n-1][m-1]
Top-Down
for (int i = 0; i < coins.size(); ++i) {
Bottom-Up
if (coins[i] <= j) {
Distinct Ways
Problem List: https://leetcode.com/list/55ajm50i
Statement
Given a target find a number of distinct ways to reach the target.
Approach
Sum all possible ways to reach the current state.
routes[i] = routes[i-1] + routes[i-2], ... , + routes[i-k]
Generate sum for all values in the target and return the value for the target.
Top-Down
Bottom-Up
if (ways[j] <= i) {
return dp[target]
Similar Problems
Top-Down
int result = climbStairs(n-1, memo) + climbStairs(n-2, memo);
Bottom-Up
for (int stair = 2; stair <= n; ++stair) {
dp[stair] += dp[stair-step];
Top-Down
int result = UniquePaths(x-1, y) + UniquePaths(x, y-1);
Bottom-Up
for (int i = 1; i < m; ++i) {
}
1155. Number of Dice Rolls With Target Sum Medium
vector<int> new_ways(target+1);
new_ways[already] %= mod;
ways = new_ways;
Merging Intervals
Statement
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.
Approach
Find all optimal solutions for every interval and return the best possible answer.
// from i to j
Get the best from the left and right sides and add a solution for the current position.
Top-Down
Bottom-Up
for(int l = 1; l<n; l++) {
int j = i+l;
return dp[0][n-1];
int j = i+l;
return dp[0][n-1]
Similar Problems
int j = i + l;
dp[i][j] = INT_MAX;
Top-Down
for (int k = i; k <= j; ++k) {
result = max(result, topDown(nums, i, k-1, memo) + (i-1 >= 0 ? nums[i-1] : 1) * nums[k] * (j+1 < nums.size() ? nums[j+1] : 1) + topDown(nums,
k+1, j, memo));
Bottom-Up
for(int l = 1; l < n; l++) {
int j = i+l;
dp[i][j] = max(dp[i][j], (((k>i && k>0) ? dp[i][k-1] : 0) + (i>0 ? nums[i-1] : 1) * nums[k] * (j<n-1 ? nums[j+1] : 1) + ((k<j && k<n-1) ?
dp[k+1][j] : 0)));
return dp[0][n-1];
DP on Strings
General problem statement for this pattern can vary but most of the time you are given two strings where lengths of those strings are not big
Statement
// j - indexing string s2
if (s1[i-1] == s2[j-1]) {
dp[i][j] = /*code*/;
} else {
dp[i][j] = /*code*/;
If you are given one string s the approach may little vary
for (int l = 1; l < n; ++l) {
int j = i + l;
if (s[i] == s[j]) {
dp[i][j] = /*code*/;
} else {
dp[i][j] = /*code*/;
if (text1[i-1] == text2[j-1]) {
dp[i][j] = dp[i-1][j-1] + 1;
} else {
int j = i + l;
dp[i][j] = dp[i+1][j-1] + 2;
} else {
dp[i][j] = 0;
Decision Making:
Problem List: https://leetcode.com/list/55af7bu7
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.
Statement
Given a set of values find an answer with an option to choose or ignore the current value.
Approach
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.
// i - indexing a set of values
Custom sort:
bool customCompare(const pair<int, int> &a, const pair<int, int> &b) {