1--会议室II(253)
2--完全平方数(279)
主要思路:
完全背包问题,每一个平方数可以选取多次。
本题的物品组合与顺序无关,对应于组合问题,因此先遍历物品,再遍历背包。
定义dp[j]表示背包容量为j时,装满背包所需完全平方数的最少数量。
#include <iostream>
#include <vector>
class Solution {
public:
int numSquares(int n) {
std::vector<int>dp(n+1, n); // 求最少数量,因此初始化不应该为0
dp[0] = 0;
for(int i = 1; i*i <= n; i++){ // 遍历物品
for(int j = i*i; j <= n; j++){ // 遍历背包
dp[j] = std::min(dp[j], dp[j - i*i] + 1); // dp[j]表示不选取物品i*i
}
}
return dp[n];
}
};
int main(int argc, char* argv[]){
// n = 12
int test = 12;
Solution S1;
int res = S1.numSquares(test);
std::cout << res << std::endl;
return 0;
}
3--移动零
主要思路:
本题只是要保持非零元素的相对顺序,没要求保持零元素的相对顺序(卡了很久,没看清楚题意);
用双指针算法即可,左指针和右指针初始化为0,左指针指向已处理元素序列的尾部(左指针左边全是非零值),右指针指向待处理元素序列的头部;当右指针遇到非零值,交换左右指针的值即可;
#include <iostream>
#include <vector>
class Solution {
public:
void moveZeroes(std::vector<int>& nums) {
int left = 0, right = 0;
while(right < nums.size()){
if(nums[right] != 0){
std::swap(nums[left], nums[right]);
left++;
}
right++;
}
}
};
int main(int argc, char* argv[]){
// nums = [0, 1, 0, 3, 12]
Solution S1;
std::vector<int> test = {0, 1, 0, 3, 12};
S1.moveZeroes(test);
for(int num : test) std::cout << num << " ";
std::cout << std::endl;
return 0;
}