1863.找出所有子集异或和的和
解释:做本题没思路的话,强烈建议看本专栏上一篇博文
class Solution {
public:
int sum = 0;
int path = 0;
int subsetXORSum(vector<int>& nums) {
dfs(nums, 0);
return sum;
}
void dfs(vector<int>& nums, int pos){
if(pos == nums.size()){
sum += path;
return;
}
dfs(nums, pos+1);
path ^= nums[pos];
dfs(nums,pos+1);
path ^= nums[pos];//恢复现场
}
};
47.全排列2
解法一:
复用 全排列的代码,再在添加的时候检查一下是否存在该排列即可。(全排列的算法思想在前面博文已做说明)
class Solution {
public:
vector<vector<int>> res;
bool check[10] = {false};
vector<int> path;
vector<vector<int>> permuteUnique(vector<int>& nums) {
dfs(nums);
return res;
}
void dfs(vector<int>& nums) {
if (path.size() == nums.size()) {
auto it = find(res.begin(), res.end(), path);
if (it == res.end())
res.push_back(path);
return;
}
for (int i = 0; i < nums.size(); ++i) {
if (!check[i]) {
path.push_back(nums[i]);
check[i] = true;
dfs(nums);
// recovery
path.pop_back();
check[i] = false;
}
}
}
};
解释:最初的检查方法是定义一个
std::unordered_map<std::vector<int>, int> check2;
的,但是这样需要自定义比较方法,代码长度会大量增加,所以直接用迭代器找吧。不过具体示例方法有个标准代码,感兴趣可以看看;
#include <iostream>
#include <vector>
#include <unordered_map>
// 自定义哈希函数
struct VectorHash {
std::size_t operator()(const std::vector<int>& v) const {
std::size_t seed = 0;
for (int i : v) {
seed ^= std::hash<int>{}(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
// 自定义相等比较函数
struct VectorEqual {
bool operator()(const std::vector<int>& v1, const std::vector<int>& v2) const {
return v1 == v2;
}
};
int main() {
std::unordered_map<std::vector<int>, int, VectorHash, VectorEqual> check;
// 示例用法
std::vector<int> vec1 = {1, 2, 3};
check[vec1] = 42;
std::vector<int> vec2 = {1, 2, 3};
std::cout << "Value associated with vec1: " << check[vec2] << std::endl;
return 0;
}
对其使用一下:
// 自定义哈希函数
struct VectorHash {
std::size_t operator()(const std::vector<int>& v) const {
std::size_t seed = 0;
for (int i : v) {
seed ^=
std::hash<int>{}(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
// 自定义相等比较函数
struct VectorEqual {
bool operator()(const std::vector<int>& v1,
const std::vector<int>& v2) const {
return v1 == v2;
}
};
class Solution {
public:
vector<vector<int>> res;
bool check[10] = {false};
vector<int> path;
std::unordered_map<std::vector<int>, int, VectorHash, VectorEqual> check2;
vector<vector<int>> permuteUnique(vector<int>& nums) {
dfs(nums);
return res;
}
void dfs(vector<int>& nums) {
if (path.size() == nums.size()) {
// auto it = find(res.begin(), res.end(), path);
// if (it == res.end())
// res.push_back(path);
if (check2.count(path) == 0) {
res.push_back(path);
check2[path]++;
}
return;
}
for (int i = 0; i < nums.size(); ++i) {
if (!check[i]) {
path.push_back(nums[i]);
check[i] = true;
dfs(nums);
// recovery
path.pop_back();
check[i] = false;
}
}
}
};
// 自定义的哈希函数以及比较函数一定要放在soloution类的前面,或者静态成员
以上两种代码的本质没有任何区别,在算法角度来说,没有进行剪枝处理,所以运行时间较长。
解法二:进行剪枝操作
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
bool checkpos[9] = {false};
int n = 0;
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
n = nums.size();
dfs(nums, 0);
return res;
}
void dfs(vector<int>& nums, int pos) {
if (pos >= n) {
res.push_back(path);
return;
}
for (int i = 0; i < n; ++i) {
if (checkpos[i] == false && (i == 0 || nums[i] != nums[i-1] || checkpos[i-1] == true)) {
path.push_back(nums[i]);
checkpos[i] = true;
dfs(nums, pos + 1);
// recovery
path.pop_back();
checkpos[i] = false;
}
}
}
};