0%

78.子集

78. 子集

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

输入:nums = [0]
输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

C++

class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void dfs(int cur, vector<int>& nums) {
if (cur == nums.size()) {
res.push_back(path);
return;
}
// 不考虑当前位置
dfs(cur + 1, nums);

// 考虑当前位置
path.push_back(nums[cur]);
dfs(cur + 1, nums);
path.pop_back();
}

vector<vector<int>> subsets(vector<int>& nums) {
dfs(0, nums);
return res;
}
};

6352. 美丽子集的数目

给你一个由正整数组成的数组 nums 和一个 整数 k

如果 nums 的子集中,任意两个整数的绝对差均不等于 k ,则认为该子数组是一个 美丽 子集。

返回数组 nums非空美丽 的子集数目。

nums 的子集定义为:可以经由 nums 删除某些元素(也可能不删除)得到的一个数组。只有在删除元素时选择的索引不同的情况下,两个子集才会被视作是不同的子集。

示例 1:

输入:nums = [2,4,6], k = 2
输出:4
解释:数组 nums 中的美丽子集有:[2], [4], [6], [2, 6]
可以证明数组 [2,4,6] 中只存在 4 个美丽子集。

示例 2:

输入:nums = [1], k = 1
输出:1
解释:数组 nums 中的美丽数组有:[1]
可以证明数组 [1] 中只存在 1 个美丽子集。

提示:

  • 1 <= nums.length <= 20
  • 1 <= nums[i], k <= 1000

C++

// 选到x的时候,如果之前选过 x−k 或 x+k,则不能选,否则可以选
class Solution {
public:
int beautifulSubsets(vector<int> &nums, int k) {
int ans = -1; // 去掉空集
map<int,int> cnt; // 用数组实现比哈希表更快
function<void (int)> dfs = [&](int i) {
if (i == nums.size()) {
ans++;
return;
}
// 不选
dfs(i + 1);

// 选
int x = nums[i]; // 避免负数下标
if (!cnt[x - k] && !cnt[x + k]) {
++cnt[x]; // 选
dfs(i + 1);
--cnt[x]; // 恢复现场
}
};
dfs(0);
return ans;
}
};

131. 分割回文串

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例 1:

输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]

示例 2:

输入:s = "a"
输出:[["a"]]

提示:

  • 1 <= s.length <= 16
  • s 仅由小写英文字母组成

C++

class Solution {
public:
vector<vector<string>> res;
vector<string> path;

vector<vector<string>> partition(string s) {
dfs(s, 0, 0);
return res;
}


void dfs(string s, int i, int start){
if(i == s.size()){
res.push_back(path);
return;
}

// 不选 i 和 i+1 之间的逗号, (i=n-1 时右边没有逗号)
if(i < s.size() - 1) dfs(s, i + 1, start);

// 选 i 和 i+1 之间的逗号
if (isPalindrome(s, start, i)) {
path.push_back(s.substr(start, i - start + 1));
dfs(s, i + 1, i + 1);
path.pop_back(); // 恢复现场
}

}

bool isPalindrome(string &s, int left, int right) {
while (left < right)
if (s[left++] != s[right--])
return false;
return true;
}

};