代码随想录算法训练营DAY25第七章 回溯算法 part04

目录

[491. 非递减子序列](#491. 非递减子序列)

[46. 全排列](#46. 全排列)

[47. 全排列 II](#47. 全排列 II)

[51. N 皇后](#51. N 皇后)


491. 非递减子序列

哈希表记录重复元素

子集问题

cpp 复制代码
class Solution {
    vector<vector<int>>ans;
    vector<int>path;
    void dfs(vector<int>&nums,int start){
        if(path.size()>=2)ans.push_back(path);
        if(start==nums.size())return ;
        unordered_map<int,int>map;
        for(int i=start;i<nums.size();i++){
            if(path.size()&&nums[i]<path.back())continue;
            if(map[nums[i]])continue;
            map[nums[i]]++;
            path.push_back(nums[i]);
            dfs(nums,i+1);
            path.pop_back();
        }
    }
public:
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        dfs(nums,0);
        return ans;
    }
};

46. 全排列

cpp 复制代码
class Solution {
    vector<vector<int>>ans;
    vector<int>path;
    vector<bool>vis;
    void dfs(vector<int>&nums){
        if(path.size()==nums.size()){
            ans.push_back(path);
            return ;
        }
        for(int i=0;i<nums.size();i++){
            if(!vis[i]){
                vis[i]=true;
                path.push_back(nums[i]);
                dfs(nums);
                vis[i]=false;
                path.pop_back();
            }
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vis.resize(nums.size());
        dfs(nums);
        return ans;
    }
};

47. 全排列 II

去重:if(i&&nums[i]==nums[i-1]&&!vis[i-1])continue;

原理:排序后相同值相邻。此时两个相同值(左和右),如果选右不选左(vis记录状态),这会和另一次的选择选左不选右重复。所以排除掉选右不选左的情况

cpp 复制代码
class Solution {
    vector<vector<int>>ans;
    vector<int>path;
    vector<bool>vis;
    void dfs(vector<int>&nums){
        if(path.size()==nums.size()){
            ans.push_back(path);
            return ;
        }
        for(int i=0;i<nums.size();i++){
            if(i&&nums[i]==nums[i-1]&&!vis[i-1])continue;
            if(!vis[i]){
                vis[i]=true;
                path.push_back(nums[i]);
                dfs(nums);
                path.pop_back();
                vis[i]=false;
            }
        }
    }
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        vis.resize(nums.size());
        sort(nums.begin(),nums.end());
        dfs(nums);
        return ans;
    }
};

51. N 皇后

cpp 复制代码
class Solution {
    void dfs(vector<vector<string>>& res, vector<int>& path, vector<bool>& vis,
             int n, int x) {
        if (x == n) {
            vector<string> borad(n);
            for (int i = 0; i < n; i++) {
                string s="";
                for (int j = 0; j < n; j++) {
                    if (path[i]==j) {
                        s+="Q";
                    } else {
                        s+=".";
                    }
                }
                borad[i]=s;
            }
            res.push_back(borad);
            return;
        }
        for (int i = 0; i < n; i++) {
            if (!vis[i]) {
                bool flag = true;
                for (int j = 0; j < x; j++) {
                    if (abs(x-j)==abs(i-path[j])) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    vis[i] = true;
                    path[x]=i;
                    dfs(res, path, vis, n, x + 1);
                    vis[i] = false;
                }
            }
        }
    }

public:
    vector<vector<string>> solveNQueens(int n) {
        vector<vector<string>> res;
        vector<int> path(n);
        vector<bool> vis(n);
        dfs(res, path, vis, n, 0);
        return res;
    }
};

相关推荐
亲爱的非洲野猪2 小时前
动态规划进阶:序列DP深度解析
算法·动态规划
不染尘.2 小时前
双指针算法
算法
2501_901147832 小时前
题解:有效的正方形
算法·面试·职场和发展·求职招聘
你撅嘴真丑2 小时前
习题与总结
算法
亲爱的非洲野猪2 小时前
动态规划进阶:状态机DP深度解析
算法·动态规划
dragoooon343 小时前
[hot100 NO.91~95]
算法
June bug3 小时前
(#字符串处理)字符串中第一个不重复的字母
python·leetcode·面试·职场和发展·跳槽
windows_63 小时前
【无标题】
算法
踢足球09293 小时前
寒假打卡:2026-01-24
数据结构·算法