50,780
社区成员
发帖
与我相关
我的任务
分享
title: 算法训练第18日
date: 2022-07-19 21:35:24
summary:
tags:
categories:
组合总和 II
class Solution {
private:
vector<vector<int>> res;
public:
vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
sort(candidates.begin() ,candidates.end());
vector<int> temp;
dfs(candidates ,target ,0 ,candidates.size() ,temp);
return res;
}
void dfs(vector<int>& candidates ,int target ,int start ,int end ,vector<int>& temp){
if(target == 0){
res.push_back(temp);
return;
}
for(int i = start;i < end;i++){
if(i > start && candidates[i] == candidates[i - 1]) continue;
temp.push_back(candidates[i]);
if(target - candidates[i] < 0){
temp.pop_back();
break;
}
dfs(candidates ,target - candidates[i] ,i + 1 ,end ,temp);
temp.pop_back();
}
}
};
全排列
class Solution {
public:
vector<vector<int>> ans; //答案
vector<int> temp; //临时变量
void DFS(vector<int>& nums, int n)
{
//出口
if(n == nums.size())
{
ans.push_back(temp);
return;
}
for(int i = 0; i < nums.size(); ++i)
{
//判断是否用过
if(nums[i] >= -10)
{
temp.push_back(nums[i]);
nums[i] -= 30; //数字范围为-10到10,所以我们可以将他变小来判断是否用过
DFS(nums, n+1);
nums[i] += 30; //复原
temp.pop_back();
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
DFS(nums, 0);
return ans;
}
};
火柴拼正方形
class Solution {
public:
vector<int> nums;
vector<bool> st;
bool makesquare(vector<int>& matchsticks) {
nums = matchsticks;
st.resize(nums.size());
// 剪枝1:由大到小排列
sort(nums.begin(), nums.end(), greater<int>());
int sum = 0;
for (auto x: nums)
sum += x;
if (sum % 4)
return false;
sum /= 4;
return dfs(0, 0, sum, 0);
}
bool dfs(int u, int cur, int len, int cnt)
{
if (cnt == 3)
return true;
if (cur == len)
return dfs(0, 0, len, cnt + 1);
for (int i = u; i < nums.size(); i ++ )
{
if (st[i])
continue;
st[i] = true;
if (dfs(i + 1, cur + nums[i], len, cnt))
return true;
st[i] = false;
// 剪枝2:跳过长度相同的火柴
while (i + 1 < nums.size() && nums[i + 1] == nums[i])
i ++ ;
// 剪枝3:如果当前是第一根或者最后一根火柴
if (!cur || cur + nums[i] == len)
return false;
}
return false;
}
};