LeetCode经典题

mac2022-06-30  18

17.电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

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

示例:

输入:“23” 输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]. 说明: 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

class Solution { public: vector<string> ans; char ops[10][10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; vector<string> letterCombinations(string digits) { dfs(digits, 0, ""); return ans; } void dfs(string &digits, int u, string path) { if(u == digits.size()) { if(path.size()) ans.push_back(path); return; } int v = digits[u] - '0'; for(int i = 0; ops[v][i]; i ++) { dfs(digits, u + 1, path + ops[v][i]); } } };

46.全排列

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

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

[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] class Solution { public: vector<vector<int>> ans; vector<int> path; vector<bool> st; vector<vector<int>> permute(vector<int>& nums) { st = vector<bool>(nums.size(), false); dfs(nums, 0); return ans; } void dfs(vector<int> &nums, int u) { if(u == nums.size()) { ans.push_back(path); return; } for(int i = 0; i < nums.size(); i ++) { if(!st[i]) { st[i] = true; path.push_back(nums[i]); dfs(nums, u + 1); st[i] = false; path.pop_back(); } } } };

47.全排列2

给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:

输入: [1,1,2] 输出:

[ [1,1,2], [1,2,1], [2,1,1] ] class Solution { public: vector<vector<int>> ans; vector<int> path; vector<bool> st; vector<vector<int>> permuteUnique(vector<int>& nums) { sort(nums.begin(), nums.end()); st = vector<bool>(nums.size(), false); path = vector<int>(nums.size()); dfs(nums, 0, 0); return ans; } void dfs(vector<int> &nums, int u, int start) { if(u == nums.size()) { ans.push_back(path); return; } for(int i = start; i < nums.size(); i ++) { if(st[i]) continue; path[i] = nums[u], st[i] = true; if(u + 1 < nums.size() && nums[u + 1] == nums[u]) dfs(nums, u + 1, i + 1); else dfs(nums, u + 1, 0); st[i] = false; } } };

78.子集

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

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

[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] class Solution { public: vector<vector<int>> ans; vector<int> path; vector<vector<int>> subsets(vector<int>& nums) { dfs(nums, 0, path); return ans; } void dfs(vector<int> &nums, int u, vector<int> &path) { ans.push_back(path); for(int i = u; i < nums.size(); i ++) { path.push_back(nums[i]); dfs(nums, i + 1, path); path.pop_back(); } } }; class Solution { public: vector<vector<int>> ans; vector<int> path; vector<vector<int>> subsets(vector<int>& nums) { dfs(nums, 0); return ans; } void dfs(vector<int> &nums, int u) { ans.push_back(path); for(int i = u; i < nums.size(); i ++) { path.push_back(nums[i]); dfs(nums, i + 1); path.pop_back(); } } };

90.子集2

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: [1,2,2] 输出:

[ [2], [1], [1,2,2], [2,2], [1,2], [] ] class Solution { public: vector<vector<int>> ans; vector<int> path; vector<vector<int>> subsetsWithDup(vector<int>& nums) { sort(nums.begin(), nums.end()); dfs(nums, 0); return ans; } void dfs(vector<int> &nums, int u) { if(u == nums.size()) { ans.push_back(path); return; } int k = u; while(k < nums.size() && nums[k] == nums[u]) k ++; dfs(nums, k); for(int i = u; i < k; i ++) { path.push_back(nums[i]); dfs(nums, k); } while(path.size() && path.back() == nums[u]) path.pop_back(); } };

39.组合总和

给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明:

所有数字(包括 target)都是正整数。 解集不能包含重复的组合。 示例 1:

输入: candidates = [2,3,6,7], target = 7, 所求解集为:

[ [7], [2,2,3] ]

示例 2:

输入: candidates = [2,3,5], target = 8, 所求解集为:

[ [2,2,2,2], [2,3,3], [3,5] ] class Solution { public: vector<vector<int>> ans; vector<int> path; vector<vector<int>> combinationSum(vector<int>& candidates, int target) { dfs(candidates, 0, target); return ans; } void dfs(vector<int>&c, int u, int t) { if(u == c.size()) { if(!t) ans.push_back(path); return; } dfs(c, u + 1, t); while(t >= c[u]) { path.push_back(c[u]); t -= c[u]; dfs(c, u + 1, t); } while(path.size() && path.back() == c[u]) path.pop_back(); } };

40.组合总和2

给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用一次。

说明:

所有数字(包括目标数)都是正整数。 解集不能包含重复的组合。 示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8, 所求解集为:

[ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5, 所求解集为:

[ [1,2,2], [5] ] class Solution { public: vector<vector<int>> ans; vector<int> path; vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(), candidates.end()); dfs(candidates, 0, target); return ans; } void dfs(vector<int> &c, int u, int t) { if(!t) { ans.push_back(path); return; } if(u == c.size()) return; int k = u + 1; while(k < c.size() && c[k] == c[u]) k ++; dfs(c, k, t); int value = c[u]; for(int i = value, j = u; j < k && i <= t; i += value, j ++) { path.push_back(value); dfs(c, k, t - i); } while(path.size() && path.back() == value) path.pop_back(); } };

216.组合数3

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。 解集不能包含重复的组合。 示例 1:

输入: k = 3, n = 7 输出: [[1,2,4]] 示例 2:

输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]]

class Solution { public: vector<vector<int>>ans; vector<int> path; vector<vector<int>> combinationSum3(int k, int n) { dfs(k, n, 1); return ans; } void dfs(int k, int n, int start) { if(!k) { if(!n) ans.push_back(path); return; } for(int i = start; i <= 10 - k; i ++) { if(n >= i) { path.push_back(i); dfs(k - 1, n - i, i + 1); path.pop_back(); } } } };

22.括号生成

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

例如,给出 n = 3,生成结果为:

[ "((()))", "(()())", "(())()", "()(())", "()()()" ] class Solution { public: int m; vector<string> ans; vector<string> generateParenthesis(int n) { m = n; dfs("", 0, 0); return ans; } void dfs(string path, int l, int r) { if(l == m && r == m) { ans.push_back(path); return; } if(l < m) dfs(path + "(", l + 1, r); if(l > r) dfs(path + ")", l, r + 1); } };

473.火柴拼正方形

还记得童话《卖火柴的小女孩》吗?现在,你知道小女孩有多少根火柴,请找出一种能使用所有火柴拼成一个正方形的方法。不能折断火柴,可以把火柴连接起来,并且每根火柴都要用到。

输入为小女孩拥有火柴的数目,每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。

示例 1:

输入: [1,1,2,2,2] 输出: true

解释: 能拼成一个边长为2的正方形,每边两根火柴。 示例 2:

输入: [3,3,3,3,4] 输出: false

解释: 不能用所有火柴拼成一个正方形。 注意:

给定的火柴长度和在 0 到 10^9之间。 火柴数组的长度不超过15。

class Solution { public: int side; vector<bool>st; bool makesquare(vector<int>& nums) { if(!nums.size()) return false; int sum = 0; for(auto x : nums) sum += x; if(sum % 4) return false; side = sum / 4; sort(nums.begin(), nums.end()); st = vector<bool>(nums.size()); return dfs(nums, 0, side, nums.size() - 1); } bool dfs(vector<int> &nums, int count, int sum, int start) { if(!sum) { if(++count == 4) return true; return dfs(nums, count, side, nums.size() - 1); } for(int i = start; i >= 0; i --) { if(!st[i] && sum >= nums[i]) { if(i + 1 < nums.size() && !st[i + 1] && nums[i + 1] == nums[i]) continue; st[i] = true; if(dfs(nums, count, sum - nums[i], i - 1)) return true; st[i] = false; //if(nums[i] == sum || sum == side) return false; } } return false; } };

52.N皇后2

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

示例:

输入: 4 输出: 2 解释: 4 皇后问题存在如下两个不同的解法。

[ [".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ] class Solution { public: int ans, n; vector<bool> col, diag, anti_diag; int totalNQueens(int _n) { n = _n; col = vector<bool>(n); diag = anti_diag = vector<bool>(2 * n); dfs(0); return ans; } void dfs(int u) { if(u == n) { ans ++; return; } for(int i = 0; i < n; i ++) { if(!col[i] && !diag[u + i] && !anti_diag[u - i + n]) { col[i] = diag[u + i] = anti_diag[u - i + n] = true; dfs(u + 1); col[i] = diag[u + i] = anti_diag[u - i + n] = false; } } } };

37.解数独

编写一个程序,通过已填充的空格来解决数独问题。

一个数独的解法需遵循如下规则:

数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 空白格用 ‘.’ 表示。

一个数独。

答案被标成红色。

Note:

给定的数独序列只包含数字 1-9 和字符 ‘.’ 。 你可以假设给定的数独只有唯一解。 给定数独永远是 9x9 形式的。

class Solution { public: bool row[9][9], col[9][9], st[3][3][9]; void solveSudoku(vector<vector<char>>& board) { memset(row, 0, sizeof row); memset(col, 0, sizeof col); memset(st, 0, sizeof st); for(int i = 0; i < 9; i ++) for(int j = 0; j < 9; j ++) if(board[i][j] != '.') { int v = board[i][j] - '1'; row[i][v] = col[j][v] = st[i/3][j/3][v] = true; } dfs(board, 0, 0); } bool dfs(vector<vector<char>>&board, int x, int y) { if(y == 9) y = 0, x ++; if(x == 9) return true; if(board[x][y] != '.') return dfs(board, x, y + 1); for(int i = 0; i < 9; i ++) { if(board[x][y] == '.' && !row[x][i] && !col[y][i] && !st[x/3][y/3][i]) { board[x][y] = '1' + i; row[x][i] = col[y][i] = st[x/3][y/3][i] = true; if(dfs(board, x, y + 1)) return true; board[x][y] = '.'; row[x][i] = col[y][i] = st[x/3][y/3][i] = false; } } return false; } };

282.给表达式添加运算符

给定一个仅包含数字 0-9 的字符串和一个目标值,在数字之间添加二元运算符(不是一元)+、- 或 * ,返回所有能够得到目标值的表达式。

示例 1:

输入: num = “123”, target = 6 输出: [“1+2+3”, “123”] 示例 2:

输入: num = “232”, target = 8 输出: [“23+2", "2+32”] 示例 3:

输入: num = “105”, target = 5 输出: [“1*0+5”,“10-5”] 示例 4:

输入: num = “00”, target = 0 输出: [“0+0”, “0-0”, “0*0”] 示例 5:

输入: num = “3456237490”, target = 9191 输出: []

class Solution { public: vector<string>ans; vector<string> addOperators(string num, int target) { dfs(num, "", 0, 0, 0, target); return ans; } void dfs(string &num, string path, int pos, long long sum, long long mul, int target) { if(pos == num.size()) { if(sum == target) ans.push_back(path); return; } for(int i = pos; i < num.size(); i ++) { if(i > pos && num[pos] == '0') break; long long v = 0; for(int j = pos; j <= i; j ++) v = v * 10 + num[j] - '0'; string number = num.substr(pos, i - pos + 1); if(!pos) { dfs(num, number, i + 1, v, v, target); } else { dfs(num, path + '+' + number, i + 1, sum + v, v, target); dfs(num, path + '-' + number, i + 1, sum - v, -v, target); dfs(num, path + '*' + number, i + 1, sum - mul + mul * v, mul * v, target); } } } };

301.删除无效的括号

删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。

说明: 输入可能包含了除 ( 和 ) 以外的字符。

示例 1:

输入: “()())()” 输出: ["()()()", “(())()”] 示例 2:

输入: “(a)())()” 输出: ["(a)()()", “(a())()”] 示例 3:

输入: “)(” 输出: [""]

class Solution { public: set<string> ans; vector<string> removeInvalidParentheses(string s) { int left = 0, right = 0; for(auto c : s) if(c == '(') { left ++; } else if(c == ')') { if(left) left --; else right ++; } dfs(s, 0, left, right); return vector<string>(ans.begin(), ans.end()); } bool check(string s) { int cnt = 0; for(auto c : s) if(c == '(') cnt ++; else if(c == ')') { cnt --; if(cnt < 0) return false; } return cnt == 0; } void dfs(string s, int u, int left, int right) { if(u == s.size()) { if(check(s)) ans.insert(s); return; } dfs(s, u + 1, left, right); if(left > 0 && s[u] == '(') { string rans = s; s.erase(s.begin() + u); dfs(s, u, left - 1, right); s = rans; } if(right > 0 && s[u] == ')') { string rans = s; s.erase(s.begin() + u); dfs(s, u, left, right - 1); s = rans; } } };
最新回复(0)