今日任务
491.递增子序列
- 题目链接: https://leetcode.cn/problems/non-decreasing-subsequences/description/
- 题目描述:
Code
class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
vector<vector<int>> ans;
vector<int> path;
int n = nums.size();
// function<void(int)> dfs = [&](int i)->void{
// if(path.size() > 1){
// ans.emplace_back(path);
// }
// if(i == n){
// return;
// }
// vector<bool> visited(201);
// for(int j = i; j < n; j++){
// if(!path.empty() && nums[j] < path.back() || j > i && nums[j - 1] == nums[j]
// || visited[nums[j] + 100]){
// continue;
// }
// visited[nums[j] + 100] = true;
// path.push_back(nums[j]);
// dfs(j + 1);
// path.pop_back();
// }
// };
// 选或不选
function<void(int)> dfs = [&](int i)->void{
if(i == n){
if(path.size() > 1){
ans.emplace_back(path);
}
return;
}
// 不选
if(path.empty() || nums[i] != path.back()){
dfs(i + 1);
}
// 选
if(path.empty() || nums[i] >= path.back()){
path.push_back(nums[i]);
dfs(i + 1);
path.pop_back();
}
};
dfs(0);
return ans;
}
};
46.全排列
- 题目链接: https://leetcode.cn/problems/permutations/description/
- 题目描述:
Code
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> ans;
int n = nums.size();
vector<int> path(n);
// vector<bool> visit(n);
// function<void(int)> dfs = [&](int i)->void{
// if(i == n){
// ans.emplace_back(path);
// return;
// }
// for(int j = 0; j < n; j++){
// if(!visit[j]){
// path[i] = nums[j]; //
// visit[j] = true;
// dfs(i + 1); //
// visit[j] = false;
// }
// }
// };
function<void(int)> dfs = [&](int i)->void{
if(i == n){
ans.emplace_back(path);
return;
}
for(int j = 0; j < n; j++){
if(nums[j] <= 10){
path[i] = nums[j]; //
nums[j] += 21;
dfs(i + 1); //
nums[j] -= 21;
}
}
};
dfs(0);
return ans;
}
};
47.全排列 II
- 题目链接: https://leetcode.cn/problems/permutations-ii/description/
- 题目描述:
Code
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> ans;
int n = nums.size();
vector<int> path;
ranges::sort(nums);
vector<int> visited(n);
function<void(int)> dfs = [&](int i)->void{
if(i == n){
ans.emplace_back(path);
return;
}
for(int j = 0; j < n; j++){
if(visited[j] || j > 0 && nums[j] == nums[j - 1] && !visited[j - 1]){
continue;
}
path.push_back(nums[j]);
visited[j] = true;
dfs(i + 1);
visited[j] = false;
path.pop_back();
}
};
dfs(0);
return ans;
}
};
332.重新安排行程
- 题目链接: https://leetcode.cn/problems/reconstruct-itinerary/description/
- 题目描述:
Code
class Solution {
public:
vector<string> findItinerary(vector<vector<string>>& tickets) {
vector<string> ans = {"JFK"};
unordered_map<string, map<string, int>> targets;
for(auto &ticket : tickets){
targets[ticket[0]][ticket[1]]++;
}
function<bool(int)> dfs = [&](int i)->bool{
if(ans.size() == i + 1){
return true;
}
for(auto &[destination, cnt] : targets[ans.back()]){
if(cnt > 0){
ans.push_back(destination);
cnt--;
if(dfs(i)){
return true;
}
ans.pop_back();
cnt++;
}
}
return false;
};
dfs(tickets.size());
return ans;
}
};
51.N皇后
- 题目链接: https://leetcode.cn/problems/n-queens/
- 题目描述:
Code
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> ans;
vector<int> columns(n);
vector<bool> on_path(n), diag1(2 * n - 1), diag2(2 * n - 1);
function<void(int)> dfs = [&](int r)->void {
if(r == n){
vector<string> board(n);
for(int i = 0; i < n; i++){
board[i] = string(columns[i], '.') + 'Q' + string(n - 1 - columns[i], '.');
}
ans.emplace_back(board);
return;
}
for(int c = 0; c < n; c++){
int rc = r - c + n - 1;
if(!on_path[c] && !diag1[r + c] && !diag2[rc]){
columns[r] = c;
on_path[c] = diag1[r + c] = diag2[rc] = true;
dfs(r + 1);
on_path[c] = diag1[r + c] = diag2[rc] = false;
}
}
};
dfs(0);
return ans;
}
};
37.解数独
- 题目链接: https://leetcode.cn/problems/sudoku-solver/
- 题目描述:
Code
class Solution {
public:
void solveSudoku(vector<vector<char>>& board) {
// function<bool(int, int, char)> isValid = [&](int row, int column, char val)->bool{
// for(int i = 0; i < 9; i++){
// if(board[row][i] == val || board[i][column] == val){
// return false;
// }
// }
// int startRow = (row / 3) * 3;
// int startCol = (column / 3) * 3;
// for(int i = startRow; i < startRow + 3; i++){
// for(int j = startCol; j < startCol + 3; j++){
// if(board[i][j] == val){
// return false;
// }
// }
// }
// return true;
// };
// function<bool()> dfs = [&]()->bool{
// for(int i = 0; i < 9; i++){
// for(int j = 0; j < 9; j++){
// if(board[i][j] == '.'){
// for(char c = '1'; c <= '9'; c++){
// if(isValid(i, j, c)){
// board[i][j] = c;
// if(dfs()){
// return true;
// }
// board[i][j] = '.';
// }
// }
// return false;
// }
// }
// }
// return true;
// };
// dfs();
// bitset
vector<bitset<9>> rows(9, bitset<9>());
vector<bitset<9>> columns(9, bitset<9>());
vector<vector<bitset<9>>> cells(3, vector<bitset<9>>(3, bitset<9>()));
function<bitset<9>(int, int)> getPossibleStatus = [&](int x, int y)->bitset<9>{
return ~(rows[x] | columns[y] | cells[x / 3][y / 3]);
};
function<vector<int>()> getNext = [&]()->vector<int>{
vector<int> ret;
int minCnt = 10;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
if(board[i][j] != '.'){
continue;
}
auto cur = getPossibleStatus(i, j);
if(cur.count() >= minCnt){
continue;
}
ret = {i, j};
minCnt = cur.count();
}
}
return ret;
};
function<void(int ,int ,int , bool)> fillNum = [&](int x, int y, int n, bool fillFlag)->void{
rows[x][n] = (fillFlag) ? 1 :0;
columns[y][n] = (fillFlag) ? 1 : 0;
cells[x / 3][y / 3][n] = (fillFlag) ? 1 : 0;
};
function<bool(int)> dfs = [&](int i)->bool{
if(i == 0){
return true;
}
auto next = getNext();
auto bits = getPossibleStatus(next[0], next[1]);
for(int n = 0; n < bits.size(); n++){
if(!bits.test(n)){
continue;
}
fillNum(next[0], next[1], n, true);
board[next[0]][next[1]] = n + '1';
if(dfs(i - 1)){
return true;
}
board[next[0]][next[1]] = '.';
fillNum(next[0], next[1], n, false);
}
return false;
};
int cnt = 0;
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
cnt += (board[i][j] == '.');
if(board[i][j] == '.'){
continue;
}
int n = board[i][j] - '1';
rows[i] |= (1 << n);
columns[j] |= (1 << n);
cells[i / 3][j / 3] |= (1 << n);
}
}
dfs(cnt);
}
};