You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night. Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
Example 1:
Input: nums = [1,2,3,1] Output: 4 Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3). Total amount you can rob = 1 + 3 = 4.
privateintbacktracking(int[] nums, int i, int[] memo) { if (i >= nums.length) return0; if (memo[i] != -1) return memo[i]; memo[i] = Math.max(backtracking(nums, i+1, memo), backtracking(nums, i+2, memo)+nums[i]); return memo[i]; } }
377. Combination Sum IV
1. Problem Description
Given an array of distinct integers nums and a target integer target, return the number of possible combinations that add up to target. The test cases are generated so that the answer can fit in a 32-bit integer.
Example 1:
Input: nums = [1,2,3], target = 4 Output: 7 Explanation: The possible combination ways are: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) Note that different sequences are counted as different combinations.
privatevoidbacktracking(int[] nums, int i, int target) { if (target == 0) { ++res; return; } if (i == nums.length || nums[i] > target) return; // skip backtracking(nums, i+1, target); // pick up backtracking(nums, 0, target-nums[i]); // 0 instead of i or i+1 } }
privateintbacktracking(int[] nums, int target, int[] memo) { if (memo[target] != -1) return memo[target]; intres=0; for (int num: nums) { if (num > target) continue; res += backtracking(nums, target-num, memo); } memo[target] = res; return res; } }
2466. Count Ways To Build Good Strings
1. Problem Description
Given the integers zero, one, low, and high, we can construct a string by starting with an empty string, and then at each step perform either of the following:
Append the character '0'zero times.
Append the character '1'one times.
This can be performed any number of times. A good string is a string constructed by the above process having a length between low and high (inclusive). Return the number of different good strings that can be constructed satisfying these properties. Since the answer can be large, return it modulo${10}^9 + 7$.
Example 1:
Input: low = 3, high = 3, zero = 1, one = 1 Output: 8 Explanation: One possible valid good string is "011". It can be constructed as follows: "" -> "0" -> "01" -> "011". All binary strings from "000" to "111" are good strings in this example.
2. Solution
依然套用回溯三要素:
当前操作: 向当前字符串添加zero次0, 或添加one次1
子操作: 返回剩余字符长度的情况下, 长度满足[low, high]的组合数
边界条件:
字符串长度超过high, 返回0
字符串长度位于[low, high]之间, 组合数+1
classSolution { publicintcountGoodStrings(int low, int high, int zero, int one) { return backtracking(low, high, zero, one, 0); }
privateintbacktracking(int low, int high, int zero, int one, int i) { if (i > high) return0; intres=0; if (i >= low && i <= high) { ++res; } res += backtracking(low, high, zero, one, i+zero) + backtracking(low, high, zero, one, i+one); return res; } }
记忆化搜索: 用memo数组记录所有长度下的组合数, 减少重复回溯:
classSolution { publicintcountGoodStrings(int low, int high, int zero, int one) { int[] memo = newint[high+1]; Arrays.fill(memo, -1); return backtracking(low, high, zero, one, 0, memo); }
privateintbacktracking(int low, int high, int zero, int one, int i, int[] memo) { if (i > high) return0; if (memo[i] != -1) return memo[i]; longres=0; if (i >= low && i <= high) { ++res; } res += backtracking(low, high, zero, one, i+zero, memo) + backtracking(low, high, zero, one, i+one, memo); memo[i] = (int)(res % 1000000007); return memo[i]; } }
修改为DP:
classSolution { publicintcountGoodStrings(int low, int high, int zero, int one) { int[] memo = newint[high+1]; intMOD= (int)(1e9 + 7), res = 0; memo[0] = 1; for (inti=0; i <= high; i++) { if (i >= zero) memo[i] = (memo[i] + memo[i-zero]) % MOD; if (i >= one) memo[i] = (memo[i] + memo[i-one]) % MOD; if (i >= low) res = (res + memo[i]) % MOD; } return res; } }
740. Delete and Earn
1. Problem Description
You are given an integer array nums. You want to maximize the number of points you get by performing the following operation any number of times:
Pick any nums[i] and delete it to earn nums[i] points. Afterwards, you must delete every element equal to nums[i] - 1 and every element equal to nums[i] + 1. Return the maximum number of points you can earn by applying the above operation some number of times.
Example 1:
Input: nums = [3,4,2] Output: 6 Explanation: You can perform the following operations: - Delete 4 to earn 4 points. Consequently, 3 is also deleted. nums = [2]. - Delete 2 to earn 2 points. nums = []. You earn a total of 6 points.
privateintbacktracking(int i, int max, int[] count, int[] memo) { if (i > max) return0; if (count[i] == 0) return backtracking(i+1, max, count, memo); if (memo[i] != -1) return memo[i]; memo[i] = Math.max(backtracking(i+1, max, count, memo), i*count[i]+backtracking(i+2, max, count, memo)); return memo[i]; } }
2320. Count Number of Ways to Place Houses
1. Problem Description
There is a street with n * 2plots, where there are n plots on each side of the street. The plots on each side are numbered from 1 to n. On each plot, a house can be placed. Return the number of ways houses can be placed such that no two houses are adjacent to each other on the same side of the street. Since the answer may be very large, return it modulo${10}^9 + 7$. Note that if a house is placed on the $i^{th}$ plot on one side of the street, a house can also be placed on the $i^{th}$ plot on the other side of the street.
Example 1:
Input: n = 1 Output: 4 Explanation: Possible arrangements: 1. All plots are empty. 2. A house is placed on one side of the street. 3. A house is placed on the other side of the street. 4. Two houses are placed, one on each side of the street.