100)三角形中最小路径之和
从下到上,不占其他空间
class Solution{
public:
int minimumTotal(vector<vector<int>>& triangle){
for(int i=triangle.size()-2; i>=0; i--){
for(int j=0; j<=i; j++){
triangle[i][j] = min(triangle[i+1][j], triangle[i+1][j+1]) + triangle[i][j]; }
}
return triangle[0][0];
}
};
从上到下,占n**2空间
class Solution{
public:
int minimumTotal(vector<vector<int>>& triangle){
int n = triangle.size();
vector<vector<int>> f(n, vector<int>(n));
f[0][0] = triangle[0][0];
for(int i=1; i<n; i++){
f[i][0] = f[i-1][0] + triangle[i][0];
for(int j=1; j<i; j++)
f[i][j] = min(f[i-1][j], f[i-1][j-1]) + triangle[i][j];
f[i][i] = f[i-1][i-1] + triangle[i][i];
}
return *min_element(f[n-1].begin(), f[n-1].end());
}
};
101)分割等和子集
class Solution{
public:
bool canPartition(vector<int>& nums){
int sum = 0;
for(int num : nums)
sum += num;
if(sum % 2) return false;
sum = sum/2;
vector<int> dp(sum+1, 0);
dp[0] = true;
for(int num : nums){
for(int j=sum; j>=num; j--){
dp[j] = dp[j] || dp[j-num];
}
}
return dp[sum];
}
};
102)加减的目标值
回溯法
class Solution{
public:
int count = 0;
int findTargetSumWays(vector<int>& nums, int target){
backtrack(nums, target, 0, 0);
return count;
}
void backtrack(vector<int>& nums, int target, int index, int sum){
if(index == nums.size()){
if(sum==target)
count++;
}
else{
backtrack(nums, target, index+1, sum+nums[index]);
backtrack(nums, target, index+1, sum-nums[index]);
}
}
};
动态规划
class Solution{
public:
int findTargetSumWays(vector<int>& nums, int target){
int sum = 0;
for(auto num : nums)
sum += num;
int diff = sum - target;
if(diff<0 || diff%2) return 0;
diff = diff/2;
vector<int> dp(diff+1);
dp[0] = true;
for(auto num : nums){
for(int j=diff; j>=num; j--){
dp[j] += dp[j-num];
}
}
return dp[diff];
}
};