LeetCode:DFS综合练习
简单
1863. 找出所有子集的异或总和再求和
一个数组的 异或总和 定义为数组中所有元素按位
XOR的结果;如果数组为 空 ,则异或总和为0。
- 例如,数组
[2,5,6]的 异或总和 为2 XOR 5 XOR 6 = 1。给你一个数组
nums,请你求出nums中每个 子集 的 异或总和 ,计算并返回这些值相加之 和 。**注意:**在本题中,元素 相同 的不同子集应 多次 计数。
数组
a是数组b的一个 子集 的前提条件是:从b删除几个(也可能不删除)元素能够得到a。示例 1:
输入:nums = [1,3] 输出:6 解释:[1,3] 共有 4 个子集: - 空子集的异或总和是 0 。 - [1] 的异或总和为 1 。 - [3] 的异或总和为 3 。 - [1,3] 的异或总和为 1 XOR 3 = 2 。 0 + 1 + 3 + 2 = 6示例 2:
输入:nums = [5,1,6] 输出:28 解释:[5,1,6] 共有 8 个子集: - 空子集的异或总和是 0 。 - [5] 的异或总和为 5 。 - [1] 的异或总和为 1 。 - [6] 的异或总和为 6 。 - [5,1] 的异或总和为 5 XOR 1 = 4 。 - [5,6] 的异或总和为 5 XOR 6 = 3 。 - [1,6] 的异或总和为 1 XOR 6 = 7 。 - [5,1,6] 的异或总和为 5 XOR 1 XOR 6 = 2 。 0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28示例 3:
输入:nums = [3,4,5,6,7,8] 输出:480 解释:每个子集的全部异或总和值之和为 480 。提示:
1 <= nums.length <= 121 <= nums[i] <= 20
int ans = 0;
int path = 0;int subsetXORSum(vector<int>& nums) {dfs(nums, 0);return ans;
}void dfs(vector<int>& nums, int pos) {ans += path;for (int i = pos; i < nums.size(); ++i) {path ^= nums[i];dfs(nums, i + 1);path ^= nums[i];}
}
面试题 08.06. 汉诺塔问题
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。
你需要原地修改栈。
示例 1:
输入:A = [2, 1, 0], B = [], C = []输出:C = [2, 1, 0]示例 2:
输入:A = [1, 0], B = [], C = []输出:C = [1, 0]提示:
- A 中盘子的数目不大于 14 个。
void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {move(A, B, C, A.size());
}void move(vector<int>& A, vector<int>& B, vector<int>& C, int n) {if (n == 1) {C.push_back(A.back());A.pop_back();return;}move(A, C, B, n - 1); // 将A上的n-1个借助C移到B上C.push_back(A.back());A.pop_back();move(B, A, C, n - 1); // 将B上的n-1个借助A移到C上
}
中等
17. 电话号码的字母组合
给定一个仅包含数字
2-9的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
![]()
示例 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']的一个数字。
vector<string> ans;
string path;
vector<string> nums = {"", "", "abc", "def","ghi", "jkl", "mno","pqrs", "tuv", "wxyz"
};vector<string> letterCombinations(string digits) {if (digits.size() == 0) {return ans;}dfs(digits, 0);return ans;
}void dfs(string digits, int pos) {if (path.size() == digits.size()) {ans.push_back(path);return;}int n = digits[pos] - '0';string str = nums[n];for (int i = 0; i < str.size(); ++i) {path.push_back(str[i]);dfs(digits, pos + 1);path.pop_back();}
}
22. 括号生成
数字
n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"]示例 2:
输入:n = 1 输出:["()"]提示:
1 <= n <= 8
vector<string> ans;
string path;vector<string> generateParenthesis(int n) {dfs(n, 0, 0);return ans;
}void dfs(int n, int left, int right) {if (left + right == 2 * n) {ans.push_back(path);return;}if (left < n) {path.push_back('(');dfs(n, left + 1, right);path.pop_back();}if (right < left) {path.push_back(')');dfs(n, left, right + 1);path.pop_back();}
}
39. 组合总和
给你一个 无重复元素 的整数数组
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
vector<vector<int>> ans;
vector<int> path;vector<vector<int>> combinationSum(vector<int>& candidates, int target) {dfs(candidates, target, 0, 0);return ans;
}void dfs(vector<int>& candidates, int target, int sum, int pos) {if (sum > target) {return;}if (sum == target) {ans.push_back(path);return;}for (int i = pos; i < candidates.size(); ++i) {path.push_back(candidates[i]);dfs(candidates, target, sum + candidates[i], i);path.pop_back();}
}
46. 全排列
给定一个不含重复数字的数组
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 <= 6-10 <= nums[i] <= 10nums中的所有整数 互不相同
vector<vector<int>> ans;
vector<int> path;
vector<bool> vis;vector<vector<int>> permute(vector<int>& nums) {int n = nums.size();vis = vector<bool>(n, false);dfs(nums);return ans;
}void dfs(vector<int>& nums) {int n = nums.size();if (path.size() == n) {ans.push_back(path);return;}for (int i = 0; i < n; ++i) {if (vis[i] == false) {path.push_back(nums[i]);vis[i] = true;dfs(nums);path.pop_back();vis[i] = false;}}
}
47. 全排列 II
给定一个可包含重复数字的序列
nums,按任意顺序 返回所有不重复的全排列。示例 1:
输入:nums = [1,1,2] 输出: [[1,1,2],[1,2,1],[2,1,1]]示例 2:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]提示:
1 <= nums.length <= 8-10 <= nums[i] <= 10
vector<vector<int>> ans;
vector<int> path;
vector<bool> vis;vector<vector<int>> permuteUnique(vector<int>& nums) {sort(nums.begin(), nums.end());vis = vector<bool>(nums.size(), false);dfs(nums, 0);return ans;
}void dfs(vector<int>& nums, int pos) {if (path.size() == nums.size()) {ans.push_back(path);return;}for (int i = 0; i < nums.size(); ++i) {if (vis[i] == true || (i > 0 && nums[i - 1] == nums[i] && vis[i - 1] == true)) {continue;}path.push_back(nums[i]);vis[i] = true;dfs(nums, i + 1);vis[i] = false;path.pop_back();}
}
50. Pow(x, n)
实现 pow(x, n) ,即计算
x的整数n次幂函数(即,xn)。示例 1:
输入:x = 2.00000, n = 10 输出:1024.00000示例 2:
输入:x = 2.10000, n = 3 输出:9.26100示例 3:
输入:x = 2.00000, n = -2 输出:0.25000 解释:2-2 = 1/22 = 1/4 = 0.25提示:
-100.0 < x < 100.0-2^31 <= n <= 2^31-1n是一个整数- 要么
x不为零,要么n > 0。-10^4 <= x^n <= 10^4
double myPow(double x, int n) {return n >= 0 ? quickMul(x, n) : 1.0 / quickMul(x, -(long long)n);
}double quickMul(double x, long long n) {if (n == 0) {return 1.0;}double tmp = quickMul(x, n / 2);return (n % 2 ? tmp * tmp * x : tmp * tmp);
}
77. 组合
给定两个整数
n和k,返回范围[1, n]中所有可能的k个数的组合。你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2:
输入:n = 1, k = 1 输出:[[1]]提示:
1 <= n <= 201 <= k <= n
vector<vector<int>> ans;
vector<int> path;vector<vector<int>> combine(int n, int k) {dfs(n, k, 1);return ans;
}void dfs(int n, int k, int pos) {if (path.size() == k) {ans.push_back(path);return;}for (int i = pos; i <= n; ++i) {path.push_back(i);dfs(n, k, i + 1);path.pop_back();}
}
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] <= 10nums中的所有元素 互不相同
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 pos) {if (pos == nums.size()) {ans.push_back(path);return;}dfs(nums, pos + 1);path.push_back(nums[pos]);dfs(nums, pos + 1);path.pop_back();
}
另一种方法
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 pos) {ans.push_back(path);for (int i = pos; i < nums.size(); ++i) {path.push_back(nums[i]);dfs(nums, i + 1);path.pop_back();}
}
79. 单词搜索
给定一个
m x n二维字符网格board和一个字符串单词word。如果word存在于网格中,返回true;否则,返回false。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例 1:
![]()
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 输出:true示例 2:
![]()
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE" 输出:true示例 3:
![]()
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB" 输出:false提示:
m == board.lengthn = board[i].length1 <= m, n <= 61 <= word.length <= 15board和word仅由大小写英文字母组成
vector<vector<bool>> vis;
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};bool exist(vector<vector<char>>& board, string word) {int n = board.size(), m = board[0].size();vis = vector<vector<bool>>(n, vector<bool>(m, false));for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (board[i][j] == word[0]) {vis[i][j] = true;if (dfs(board, word, i, j, 1) == true) {return true;}vis[i][j] = false;}}}return false;
}bool dfs(vector<vector<char>>& board, const string& word, int x, int y, int pos) {if (pos == word.size()) {return true;}int n = board.size(), m = board[0].size();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < n && ny >= 0 && ny < m && board[nx][ny] == word[pos] && vis[nx][ny] == false) {vis[nx][ny] = true;if (dfs(board, word, nx, ny, pos + 1) == true) {return true;}vis[nx][ny] = false;}}return false;
}
494. 目标和
给你一个非负整数数组
nums和一个整数target。向数组中的每个整数前添加
'+'或'-',然后串联起所有整数,可以构造一个 表达式 :
- 例如,
nums = [2, 1],可以在2之前添加'+',在1之前添加'-',然后串联起来得到表达式"+2-1"。返回可以通过上述方法构造的、运算结果等于
target的不同 表达式 的数目。示例 1:
输入:nums = [1,1,1,1,1], target = 3 输出:5 解释:一共有 5 种方法让最终目标和为 3 。 -1 + 1 + 1 + 1 + 1 = 3 +1 - 1 + 1 + 1 + 1 = 3 +1 + 1 - 1 + 1 + 1 = 3 +1 + 1 + 1 - 1 + 1 = 3 +1 + 1 + 1 + 1 - 1 = 3示例 2:
输入:nums = [1], target = 1 输出:1提示:
1 <= nums.length <= 200 <= nums[i] <= 10000 <= sum(nums[i]) <= 1000-1000 <= target <= 1000
int ans = 0;int findTargetSumWays(vector<int>& nums, int target) {dfs(nums, target, 0, 0);return ans;
}void dfs(vector<int>& nums, int target, int pos, int sum) {if (pos == nums.size()) {if (target == sum) {ans++;}return;}dfs(nums, target, pos + 1, sum + nums[pos]);dfs(nums, target, pos + 1, sum - nums[pos]);
}
526. 优美的排列
假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组
perm(下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 :
perm[i]能够被i整除i能够被perm[i]整除给你一个整数
n,返回可以构造的 优美排列 的 数量 。示例 1:
输入:n = 2 输出:2 解释: 第 1 个优美的排列是 [1,2]:- perm[1] = 1 能被 i = 1 整除- perm[2] = 2 能被 i = 2 整除 第 2 个优美的排列是 [2,1]:- perm[1] = 2 能被 i = 1 整除- i = 2 能被 perm[2] = 1 整除示例 2:
输入:n = 1 输出:1提示:
1 <= n <= 15
int ans;
vector<bool> vis;int countArrangement(int n) {vis = vector<bool>(n, false);dfs(n, 1);return ans;
}void dfs(int n, int pos) {if (pos == n + 1) {ans++;return;}for (int i = 1; i <= n; ++i) {if (vis[i] == false && (i % pos == 0 || pos % i == 0)) {vis[i] = true;dfs(n, pos + 1);vis[i] = false;}}
}
784. 字母大小写全排列
给定一个字符串
s,通过将字符串s中的每个字母转变大小写,我们可以获得一个新的字符串。返回 所有可能得到的字符串集合 。以 任意顺序 返回输出。
示例 1:
输入:s = "a1b2" 输出:["a1b2", "a1B2", "A1b2", "A1B2"]示例 2:
输入: s = "3z4" 输出: ["3z4","3Z4"]提示:
1 <= s.length <= 12s由小写英文字母、大写英文字母和数字组成
vector<string> ans;vector<string> letterCasePermutation(string s) {dfs(s, 0);return ans;
}void dfs(string s, int pos) {if (pos == s.size()) {ans.push_back(s);return;}if (isdigit(s[pos])) {dfs(s, pos + 1);} else {s[pos] = tolower(s[pos]);dfs(s, pos + 1);s[pos] = toupper(s[pos]);dfs(s, pos + 1);}
}
1219. 黄金矿工
你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为
m * n的网格grid进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是0。为了使收益最大化,矿工需要按以下规则来开采黄金:
- 每当矿工进入一个单元,就会收集该单元格中的所有黄金。
- 矿工每次可以从当前位置向上下左右四个方向走。
- 每个单元格只能被开采(进入)一次。
- 不得开采(进入)黄金数目为
0的单元格。- 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。
示例 1:
输入:grid = [[0,6,0],[5,8,7],[0,9,0]] 输出:24 解释: [[0,6,0],[5,8,7],[0,9,0]] 一种收集最多黄金的路线是:9 -> 8 -> 7。示例 2:
输入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]] 输出:28 解释: [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]] 一种收集最多黄金的路线是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。提示:
1 <= grid.length, grid[i].length <= 150 <= grid[i][j] <= 100- 最多 25 个单元格中有黄金。
int ans = 0, path = 0;
vector<vector<bool>> vis;
const int dx[4] = {0, 0, 1, -1};
const int dy[4] = {1, -1, 0, 0};int getMaximumGold(vector<vector<int>>& grid) {int n = grid.size(), m = grid[0].size();vis = vector<vector<bool>>(n, vector<bool>(m, false));for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (grid[i][j] != 0) {dfs(grid, i, j);}}}return ans;
}void dfs(vector<vector<int>>& grid, int x, int y) {path += grid[x][y];vis[x][y] = true;ans = max(ans, path);int n = grid.size(), m = grid[0].size();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] != 0 && vis[nx][ny] == false) {dfs(grid, nx, ny);}}path -= grid[x][y];vis[x][y] = false;
}
困难
37. 解数独
编写一个程序,通过填充空格来解决数独问题。
数独的解法需 遵循如下规则:
- 数字
1-9在每一行只能出现一次。- 数字
1-9在每一列只能出现一次。- 数字
1-9在每一个以粗实线分隔的3x3宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用
'.'表示。示例 1:
输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]] 输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]] 解释:输入的数独如上图所示,唯一有效的解决方案如下所示:提示:
board.length == 9board[i].length == 9board[i][j]是一位数字或者'.'- 题目数据 保证 输入数独仅有一个解
bool row[10][10], col[10][10], grid[3][3][10];void solveSudoku(vector<vector<char>>& board) {for (int i = 0; i < 9; ++i) {for (int j = 0; j < 9; ++j) {if (board[i][j] != '.') {int num = board[i][j] - '0';row[i][num] = col[j][num] = grid[i/3][j/3][num] = true;}}}dfs(board);
}bool dfs(vector<vector<char>>& board) {for (int i = 0; i < 9; ++i) {for (int j = 0; j < 9; ++j) {if (board[i][j] == '.') {for (int num = 1; num < 10; ++num) {if (!row[i][num] && !col[j][num] && !grid[i/3][j/3][num]) {board[i][j] = num + '0';row[i][num] = col[j][num] = grid[i/3][j/3][num] = true;if (dfs(board) == true)return true; board[i][j] = '.';row[i][num] = col[j][num] = grid[i/3][j/3][num] = false;}}return false;}}}return true;
}
51. N 皇后
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将
n个皇后放置在n×n的棋盘上,并且使皇后彼此之间不能相互攻击。给你一个整数
n,返回所有不同的 n 皇后问题 的解决方案。每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中
'Q'和'.'分别代表了皇后和空位。示例 1:
![]()
输入:n = 4 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] 解释:如上图所示,4 皇后问题存在两个不同的解法。示例 2:
输入:n = 1 输出:[["Q"]]提示:
1 <= n <= 9
通过x = 0时y = b来判断是否当前斜线上有无皇后。
vector<vector<string>> ans;
vector<string> path;
bool vis[10];
bool vis1[20]; // y - x = b
bool vis2[20]; // y + x = bvector<vector<string>> solveNQueens(int n) {path.resize(n);for (int i = 0; i < n; ++i) {path[i].append(n, '.');}dfs(n, 0);return ans;
}void dfs(int n, int y) {if (y == n) {ans.push_back(path);return;}for (int x = 0; x < n; ++x) {if (!vis[x] && !vis1[y - x + 10] && !vis2[y + x]) {path[y][x] = 'Q';vis[x] = vis1[y - x + 10] = vis2[y + x] = true;dfs(n, y + 1);path[y][x] = '.';vis[x] = vis1[y - x + 10] = vis2[y + x] = false;}}
}
980. 不同路径 III
在二维网格
grid上,有 4 种类型的方格:
1表示起始方格。且只有一个起始方格。2表示结束方格,且只有一个结束方格。0表示我们可以走过的空方格。-1表示我们无法跨越的障碍。返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目**。**
每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格。
示例 1:
输入:[[1,0,0,0],[0,0,0,0],[0,0,2,-1]] 输出:2 解释:我们有以下两条路径: 1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2) 2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)示例 2:
输入:[[1,0,0,0],[0,0,0,0],[0,0,0,2]] 输出:4 解释:我们有以下四条路径: 1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3) 2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3) 3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3) 4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)示例 3:
输入:[[0,1],[2,0]] 输出:0 解释: 没有一条路能完全穿过每一个空的方格一次。 请注意,起始和结束方格可以位于网格中的任意位置。提示:
1 <= grid.length * grid[0].length <= 20
int ans = 0, sum = 0; // sum 0的个数
vector<vector<bool>> vis;
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {1, -1, 0, 0};int uniquePathsIII(vector<vector<int>>& grid) {int n = grid.size(), m = grid[0].size();vis = vector<vector<bool>> (n, vector<bool>(m, false));int x, y;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (grid[i][j] == 1) {vis[i][j] = true;x = i, y = j;} else if (grid[i][j] == 0) {sum++;}}}dfs(grid, x, y, 0);return ans;
}void dfs(vector<vector<int>>& grid, int x, int y, int cnt) {if (grid[x][y] == 2 && cnt == sum + 1) { // cnt 0+2 的个数ans++;return;}int n = grid.size(), m = grid[0].size();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] != -1 && vis[nx][ny] == false) {vis[nx][ny] = true;dfs(grid, nx, ny, cnt + 1);vis[nx][ny] = false;}}
}
1 <= grid.length * grid[0].length <= 20`
int ans = 0, sum = 0; // sum 0的个数
vector<vector<bool>> vis;
const int dx[4] = {0, 0, -1, 1};
const int dy[4] = {1, -1, 0, 0};int uniquePathsIII(vector<vector<int>>& grid) {int n = grid.size(), m = grid[0].size();vis = vector<vector<bool>> (n, vector<bool>(m, false));int x, y;for (int i = 0; i < n; ++i) {for (int j = 0; j < m; ++j) {if (grid[i][j] == 1) {vis[i][j] = true;x = i, y = j;} else if (grid[i][j] == 0) {sum++;}}}dfs(grid, x, y, 0);return ans;
}void dfs(vector<vector<int>>& grid, int x, int y, int cnt) {if (grid[x][y] == 2 && cnt == sum + 1) { // cnt 0+2 的个数ans++;return;}int n = grid.size(), m = grid[0].size();for (int k = 0; k < 4; ++k) {int nx = x + dx[k], ny = y + dy[k];if (nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] != -1 && vis[nx][ny] == false) {vis[nx][ny] = true;dfs(grid, nx, ny, cnt + 1);vis[nx][ny] = false;}}
}
相关文章:
LeetCode:DFS综合练习
简单 1863. 找出所有子集的异或总和再求和 一个数组的 异或总和 定义为数组中所有元素按位 XOR 的结果;如果数组为 空 ,则异或总和为 0 。 例如,数组 [2,5,6] 的 异或总和 为 2 XOR 5 XOR 6 1 。 给你一个数组 nums ,请你求出 n…...
Perf学习
重要的能解决的问题是这些: perf_events is an event-oriented observability tool, which can help you solve advanced performance and troubleshooting functions. Questions that can be answered include: Why is the kernel on-CPU so much? What code-pa…...
齐次坐标变换+Unity矩阵变换
矩阵变换 变换(transform):指的是我们把一些数据,如点,方向向量甚至是颜色,通过某种方式(矩阵运算),进行转换的过程。 变换类型 线性变换:保留矢量加和标量乘的计算 f(x)…...
Pandas取代Excel?
有人在知乎上提问:为什么大公司不用pandas取代excel? 而且列出了几个理由:Pandas功能比Excel强大,运行速度更快,Excel除了简单和可视化界面外,没有其他更多的优势。 有个可怕的现实是,对比Exce…...
启动vite项目报Unexpected “\x88“ in JSON
启动vite项目报Unexpected “\x88” in JSON 通常是文件被防火墙加密需要寻找运维解决 重启重装npm install...
HTTP测试智能化升级:动态变量管理实战与效能跃迁
在Web应用、API接口测试等领域,测试场景的动态性和复杂性对测试数据的灵活管理提出了极高要求。传统的静态测试数据难以满足多用户并发、参数化请求及响应内容验证等需求。例如,在电商系统性能测试中,若无法动态生成用户ID、订单号或实时提取…...
关于一对多关系(即E-R图中1:n)中的界面展示优化和数据库设计
前言 一对多,是常见的数据库关系。在界面设计时,有时为了方便,就展示成逗号分割的字符串。例如:学生和爱好的界面。 存储 如果是简单存储,建立数据库:爱好,课程,存在一张表中。 但…...
【gpt生成-总览】怎样才算开发了一门编程语言,需要通过什么测试
开发一门真正的编程语言需要经历完整的设计、实现和验证过程,并通过系统的测试体系验证其完备性。以下是分阶段开发标准及测试方法: 一、语言开发核心阶段 1. 语言规范设计(ISO/IEC 标准级别) 语法规范:BNF/…...
JVM笔记【一】java和Tomcat类加载机制
JVM笔记一java和Tomcat类加载机制 java和Tomcat类加载机制 Java类加载 * loadClass加载步骤类加载机制类加载器初始化过程双亲委派机制全盘负责委托机制类关系图自定义类加载器打破双亲委派机制 Tomcat类加载器 * 为了解决以上问题,tomcat是如何实现类加载机制的…...
React 组件类型详解:类组件 vs. 函数组件
React 是一个用于构建用户界面的 JavaScript 库,其核心思想是组件化开发。React 组件可以分为类组件(Class Components)和函数组件(Function Components),它们在设计理念、使用方式和适用场景上有所不同。随…...
GPT-SoVITS 使用指南
一、简介 TTS(Text-to-Speech,文本转语音):是一种将文字转换为自然语音的技术,通过算法生成人类可听的语音输出,广泛应用于语音助手、无障碍服务、导航系统等场景。类似的还有SVC(歌声转换&…...
美信监控易:数据采集与整合的卓越之选
在当今复杂多变的运维环境中,一款具备强大数据采集与整合能力的运维管理软件对于企业的稳定运行和高效决策至关重要。美信监控易正是这样一款在数据采集与整合方面展现出显著优势的软件,以下是它的一些关键技术优势,值得每一个运维团队深入了…...
基于Redis的3种分布式ID生成策略
在分布式系统设计中,全局唯一ID是一个基础而关键的组件。随着业务规模扩大和系统架构向微服务演进,传统的单机自增ID已无法满足需求。高并发、高可用的分布式ID生成方案成为构建可靠分布式系统的必要条件。 Redis具备高性能、原子操作及简单易用的特性&…...
OCR技术与视觉模型技术的区别、应用及展望
在计算机视觉技术飞速发展的当下,OCR技术与视觉模型技术成为推动各行业智能化变革的重要力量。它们在原理、应用等方面存在诸多差异,在自动化测试领域也展现出不同的表现与潜力,下面将为你详细剖析。 一、技术区别 (一ÿ…...
End-to-End从混沌到秩序:基于LLM的Pipeline将非结构化数据转化为知识图谱
摘要:本文介绍了一种将非结构化数据转换为知识图谱的端到端方法。通过使用大型语言模型(LLM)和一系列数据处理技术,我们能够从原始文本中自动提取结构化的知识。这一过程包括文本分块、LLM 提示设计、三元组提取、归一化与去重,最终利用 NetworkX 和 ipycytoscape 构建并可…...
比特币的跨输入签名聚合(Cross-Input Signature Aggregation,CISA)
1. 引言 2024 年,人权基金会(Human Rights Foundation,简称 HRF)启动了一项研究奖学金计划,旨在探讨“跨输入签名聚合”(Cross-Input Signature Aggregation,简称 CISA)的潜在影响。…...
洛谷P1177【模板】排序:十种排序算法全解(2)
我们接着上一篇继续讲【洛谷P1177【模板】排序:十种排序算法全解(1)】 三、计数排序(Counting Sort) 仅适用于数据范围较小的情况 // Java import java.io.*; public class Main {static final int OFFSET 100000;public static void…...
MySql 三大日志(redolog、undolog、binlog)详解
确保应用运行环境的一致性和可移…...
HTTP:九.WEB机器人
概念 Web机器人是能够在无需人类干预的情况下自动进行一系列Web事务处理的软件程序。人们根据这些机器人探查web站点的方式,形象的给它们取了一个饱含特色的名字,比如“爬虫”、“蜘蛛”、“蠕虫”以及“机器人”等!爬虫概述 网络爬虫(英语:web crawler),也叫网络蜘蛛(…...
2025妈妈杯数学建模C题完整分析论文(共36页)(含模型建立、可运行代码、数据)
2025 年第十五届 MathorCup 数学建模C题完整分析论文 目录 摘 要 一、问题分析 二、问题重述 三、模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1代码(仅供参考) 4.1.4问题1求解结果(仅…...
数据结构排序算法全解析:从基础原理到实战应用
在计算机科学领域,排序算法是数据处理的核心技术之一。无论是小规模数据的简单整理,还是大规模数据的高效处理,选择合适的排序算法直接影响着程序的性能。本文将深入解析常见排序算法的核心思想、实现细节、特性对比及适用场景,帮…...
UMG:ListView
1.创建WBP_ListView,添加Border和ListView。 2.创建Object,命名为Item(数据载体,可以是其他类型)。新增变量name。 3.创建User Widget,命名为Entry(循环使用的UI载体).添加Border和Text。 4.设置Entry继承UserObjectListEntry接口。 5.Entry中对象生成时…...
每天学一个 Linux 命令(18):mv
可访问网站查看,视觉品味拉满: http://www.616vip.cn/18/index.html 每天学一个 Linux 命令(18):mv 命令功能 mv(全称:move)用于移动文件/目录或重命名文件/目录,是…...
ubuntu24.04上使用qemu和buildroot模拟vexpress-ca9开发板构建嵌入式arm linux环境
1 准备工作 1.1 安装qemu 在ubuntu系统中使用以下命令安装qemu。 sudo apt install qemu-system-arm 安装完毕后,在终端输入: qemu- 后按TAB键,弹出下列命令证明安装成功。 1.2 安装arm交叉编译工具链 sudo apt install gcc-arm-linux-gnueabihf 安装之…...
IntelliSense 已完成初始化,但在尝试加载文档时出错
系列文章目录 文章目录 系列文章目录前言一、原因二、使用步骤 前言 IntelliSense 已完成初始化,但在尝试加载文档时出错 File path: E:\QtExercise\DigitalPlatform\DigitalPlatform\main\propertyWin.ui Frame GUID:96fe523d-6182-49f5-8992-3bea5f7e6ff6 Frame …...
dumpsys--音频服务状态信息
Audio相关的信息获取指令: dumpsys media.audio_flinger dumpsys media.audio_policy dumpsys audio media.audio_flinger dumpsys media.audio_flinger 用于获取 AudioFlinger 服务的详细状态信息。 1. 命令作用 该命令输出当前系统的 音频设备状态、活跃音频流…...
【更新完毕】2025泰迪杯数据挖掘竞赛A题数学建模思路代码文章教学:竞赛论文初步筛选系统
完整内容请看文末最后的推广群 基于自然语言处理的竞赛论文初步筛选系统 基于多模态分析的竞赛论文自动筛选与重复检测模型 摘要 随着大学生竞赛规模的不断扩大,参赛论文的数量激增,传统的人工筛选方法面临着工作量大、效率低且容易出错的问题。因此&…...
服务器内存规格详解
服务器内存规格详解 一、内存安装原则与配置规范 1. 内存槽位安装规则 规则描述CPU1对应的内存槽位至少需配置一根内存禁止混用不同规格(容量/位宽/rank/高度)内存条,需保持相同Part No.推荐完全平衡的内存配置,避免通道/处理器…...
kafka集群认证
1、安装Kerberos(10.10.10.168) yum install krb5-server krb5-workstation krb5-libs -y 查看版本 klist -V Kerberos 5 version 1.20.1 编辑/etc/hosts 10.10.10.168 ms1 10.10.10.150 ms2 10.10.10.110 ms3 vim /etc/krb5.conf # Configuration snippets ma…...

