491. 非递减子序列
思路:
- 不可以排序, 否则会改变元素的顺序
- 对收获的结果有要求, num.size() >= 2, 且 num[i - 1] < num[i]
- 需要进行去重, 不能使用排序后的方法去重
- 每一层可用 unordered_set 去重
- 组合问题, for 遍历需要标记起始位置
bug:
- 一定要先判断元素是否重复, 再将元素插入
//正确步骤
if (used.find(nums[i]) != used.end()) {continue;
} else if (res_tem.empty()) { // 重复元素res_tem.push_back(nums[i]);
} else if (res_tem.back() > nums[i]) { // 非递增continue;
} else {res_tem.push_back(nums[i]);
}//错误步骤
//当res_tem为空时, 会将重复元素也添加, 一定需要先判断元素是否有使用
if (res_tem.size() == 0) { res_tem.push_back(nums[i]);
} else if (used.find(nums[i]) != used.end()) { //重复元素continue;
} else if (!(res_tem.back() <= nums[i])) { //非递增continue;
} else {res_tem.push_back(nums[i]);
}
class Solution {
public:vector<vector<int>> res;vector<int> res_tem;void myoperator(vector<int>& nums, int index) {if (res_tem.size() >= 2) {res.push_back(res_tem);}unordered_set<int> used;for (int i = index; i < nums.size(); i++) {if (used.find(nums[i]) != used.end()) {continue;} else if (res_tem.empty()) { // 重复元素res_tem.push_back(nums[i]);} else if (res_tem.back() > nums[i]) { // 非递增continue;} else {res_tem.push_back(nums[i]);}// 等效操作// if (!res_tem.empty() && nums[i] < res_tem.back()) {// continue;// }// if (used.find(nums[i]) != used.end()) {// continue;// }// res_tem.push_back(nums[i]);used.insert(nums[i]);myoperator(nums, i + 1);res_tem.pop_back();}}vector<vector<int>> findSubsequences(vector<int>& nums) {myoperator(nums, 0);return res;}
};
46.全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
思路:
- 不能使用index来跳过元素, 因为与顺序有关, 所以遍历从 i = 0 开始
- 每个元素都要遍历, 可以使用 used 数组去重
- 无法用 unordered_set 去重, 每层树枝都有相互关联, 不是去除重复数字操作
class Solution {
public:vector<vector<int>> res;vector<int> res_tem;vector<bool> uesed;void myoperator(vector<int>& nums) {if (res_tem.size() == nums.size()) {res.push_back(res_tem);return;}for (int i = 0; i < nums.size(); i++) {if (uesed[i] == true) {continue;}uesed[i] = true;res_tem.push_back(nums[i]);myoperator(nums);uesed[i] = false;res_tem.pop_back();}}vector<vector<int>> permute(vector<int>& nums) {uesed = vector<bool>(nums.size(), 0);myoperator(nums);return res;}
};
47. 全排列 II
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列
思路:
- 取叶子节点, 中间需要去除, 相同数层之间不能用同样的数值
- 排列则需要从0开始, 使用used标记使用过的元素
class Solution {
public:vector<vector<int>> res;vector<int> res_tem;vector<bool> flag;void myoperator(vector<int>& nums) {if (res_tem.size() == nums.size()) {res.push_back(res_tem);return;}unordered_set<int> used;for (int i = 0; i < nums.size(); i++) {if (used.find(nums[i]) != used.end()) {continue;}if (flag[i] == true) {continue;}flag[i] = true;used.insert(nums[i]);res_tem.push_back(nums[i]);myoperator(nums);flag[i] = false;res_tem.pop_back();}}vector<vector<int>> permuteUnique(vector<int>& nums) {flag = vector<bool>(nums.size(), false);myoperator(nums);return res;}
};
51. N 皇后
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
参考
37. 解数独
参考