主页 > 人工智能  > 

【力扣Hot100】回溯1

【力扣Hot100】回溯1
1. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [1] 输出:[[1]]

提示:

1 <= nums.length <= 610 <= nums[i] <= 10nums 中的所有整数 互不相同

题解

class Solution { public: void dfs(vector<int>& nums, vector<vector<int>>& ans, vector<bool>& used, vector<int>& path, int idx) { if(idx == nums.size()) { ans.push_back(path); return; } for(int i = 0; i < nums.size(); i ++ ) { if(used[i] == true) continue; used[i] = true; path[idx] = nums[i]; dfs(nums, ans, used, path, idx + 1); used[i] = false; } } vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> ans; vector<bool> used(nums.size(), false); vector<int> path(nums.size()); dfs(nums, ans, used, path, 0); return ans; } }; 2. 子集

给你一个整数数组 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 <= 1010 <= nums[i] <= 10nums 中的所有元素 互不相同

题解

用二进制数表示 nums 的每个位置上的值是否在集合中

class Solution { public: vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>> ans; vector<int> path; int n = nums.size(); for(int mask = 0; mask < (1 << n); mask ++ ) { path.clear(); for(int i = 0; i < n; i ++ ) { if(mask & (1 << i)) path.push_back(nums[i]); } ans.push_back(path); } return ans; } }; 3. 电话号码的组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

! assets.leetcode-cn /aliyun-lc-upload/uploads/2021/11/09/200px-telephone-keypad2svg.png

示例 1:

输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = "" 输出:[]

示例 3:

输入:digits = "2" 输出:["a","b","c"]

提示:

0 <= digits.length <= 4digits[i] 是范围 ['2', '9'] 的一个数字。

题解

class Solution { public: vector<string> d2s = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; void dfs(vector<string>& ans, string& digits, int idx, string& path) { if(idx == digits.length()) { ans.push_back(path); return; } int c = digits[idx] - '2'; for(int i = 0; i < d2s[c].length(); i ++ ) { path.push_back(d2s[c][i]); dfs(ans, digits, idx + 1, path); path.pop_back(); } } vector<string> letterCombinations(string digits) { if(digits.size() == 0) return {}; vector<string> ans; string path; int n = digits.size(); dfs(ans, digits, 0, path); return ans; } }; 4. 组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 **不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

输入:candidates =[2,3,6,7], target =7输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 7 也是一个候选, 7 = 7 。 仅有这两种组合。

示例 2:

输入:candidates = [2,3,5],target = 8 输出:[[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入:candidates =[2],target = 1 输出:[]

提示:

1 <= candidates.length <= 302 <= candidates[i] <= 40candidates 的所有元素 互不相同1 <= target <= 40

题解

dfs函数中要枚举两种情况:

放该元素,要求放了后和应该小于等于target,再dfs(idx)不放该元素,dfs(idx + 1) class Solution { public: void dfs(vector<vector<int>>& ans, vector<int>& path, vector<int>& candidates, int target, int sum, int idx) { if(idx == candidates.size()) return; if(sum == target) { ans.push_back(path); return; } // 不放 dfs(ans, path, candidates, target, sum, idx + 1); // 放 if(target >= sum + candidates[idx]) { path.push_back(candidates[idx]); dfs(ans, path, candidates, target, sum + candidates[idx], idx); path.pop_back(); } } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { vector<vector<int>> ans; vector<int> path; dfs(ans, path, candidates, target, 0, 0); return ans; } };
标签:

【力扣Hot100】回溯1由讯客互联人工智能栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【力扣Hot100】回溯1