Leetcode312. 戳气球
思路:区间动态规划
集合表示:
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示打掉
i
+
1
—
—
j
−
1
i+1——j-1
i+1——j−1区间内气球获得金币最大值,因为边界问题保证边界不能被打掉,递推关系式是:
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
]
[
j
]
,
f
[
i
]
[
k
]
+
f
[
k
]
[
j
]
+
a
[
i
]
∗
a
[
k
]
∗
a
[
j
]
)
f[i][j] = max(f[i][j], f[i][k] + f[k][j] + a[i] * a[k] * a[j])
f[i][j]=max(f[i][j],f[i][k]+f[k][j]+a[i]∗a[k]∗a[j]),假如最后一个被打掉的气球是第
k
k
k个气球,k这个气球左右两边相互独立,所以就是两边加起来,再加上打掉第
k
k
k个气球获得金币最大值
class Solution {
public:
int maxCoins(vector<int>& nums) {
int n = nums.size();
vector<int> a(n + 2, 1);
for (int i = 1; i <= n; i ++ ) a[i] = nums[i - 1];
vector<vector<int>> f(n + 2, vector<int>(n + 2));
for (int len = 3; len <= n + 2; len ++ )
for (int i = 0; i + len - 1 <= n + 1; i ++ ) {
int j = i + len - 1;
for (int k = i + 1; k < j; k ++ )
f[i][j] = max(f[i][j], f[i][k] + f[k][j] + a[i]*a[k]*a[j]);
}
return f[0][n + 1];
}
};
Leetcode322. 零钱兑换
思路:完全背包问题
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> f(amount + 1, amount + 1);
f[0] = 0;
for (int i = 0; i < coins.size(); i ++ ) {
for (int j = 1; j <= amount; j ++ )
if (coins[i] <= j)
f[j] = min(f[j], f[j - coins[i]] + 1);
}
return f[amount] == amount + 1 ? -1 : f[amount];
}
};
Leetcode337. 打家劫舍 III
思路:树上DP
题目类似于Acwing285题上司的舞会
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int rob(TreeNode* root) {
vector<int> f = dfs(root);
return max(f[0], f[1]);
}
vector<int> dfs(TreeNode* root) {
if (!root) return {0, 0};
auto l = dfs(root->left), r = dfs(root->right);
return {max(l[0], l[1]) + max(r[0], r[1]), root->val + l[0] + r[0]};
}
};
Leetcode338. 比特位计数
思路:递推
f [ i ] = f [ i > > 1 ] + ( i 取 址 1 ) f[i] = f[i >> 1] + (i 取址1) f[i]=f[i>>1]+(i取址1)返回 f f f就可以了
class Solution {
public:
vector<int> countBits(int n) {
vector<int> f(n + 1);
for (int i = 1; i <= n; i ++ )
f[i] = f[i >> 1] + (i & 1);
return f;
}
};
Leetcode347. 前 K 个高频元素
思路:计数排序的思想
哈希表统计一下每个数出现次数,用一个数组表示出现次数为0~n数有多少个,从n开始找,知道知道到k个高频的数在计数数组中的下标 r r r,在哈希表里面将出现次数 > r >r >r数返回
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> cnt;
for (auto& x : nums) cnt[x] ++ ;
int n = nums.size();
vector<int> s(n + 1);
for (auto [x, c] : cnt) s[c] ++ ;
int r = n, t = 0;
while (t < k) t += s[r -- ];
vector<int> res;
for (auto [x, c] : cnt)
if (c > r)
res.push_back(x);
return res;
}
};