牛客101:递归/回溯

目录

一、没有重复项数字的全排列

二、有重复项数字的全排列

三、岛屿数量

四、字符串的排列

五、N皇后

六、括号生成

七、矩阵最长递增路径


这个专栏写得很顺畅

一、没有重复项数字的全排列

没有重复项数字的全排列_牛客题霸_牛客网

无重复->暴力枚举,check剪枝

牛客这边好像类内成员属性不给初始化的,所以将其设置为全局变量。

cpp 复制代码
#include <vector>
bool check[7];
vector<int> path;
vector<vector<int>> ret;
int _n;
class Solution {
public:
    vector<vector<int> > permute(vector<int>& num) {
        _n=num.size();
        //题目要求
        sort(num.begin(),num.end());
        dfs(num);
        return ret;
    }
    void dfs(vector<int>&num)
    {
        if(path.size()==_n)
        {
            ret.push_back(path);
            return;
        }
        for(int i=0;i<_n;++i)
        {
            if(!check[i])
            {
                check[i]=true;
                path.push_back(num[i]);
                dfs(num);
                check[i]=false;
                path.pop_back();
            }
        }
    }
};

二、有重复项数字的全排列

有重复项数字的全排列_牛客题霸_牛客网

有重复?排序+check分层判断

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

三、岛屿数量

岛屿数量_牛客题霸_牛客网

check标记

cpp 复制代码
class Solution {
    int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1},m,n;
    bool check[301][301];
public:
    int solve(vector<vector<char>>& grid) {
        m=grid.size(),n=grid[0].size();
        int ret=0;
        for(int i=0;i<m;++i)
        {
            for(int j=0;j<n;++j)
            {
                if(grid[i][j]=='1'&&!check[i][j])
                {
                    ++ret;
                    //check!
                    dfs(grid,i,j);
                }
            }
        }
        return ret;
    }
    void dfs(vector<vector<char>>& grid,int i,int j)
    {
        check[i][j]=true;
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]=='1'&&!check[x][y])
            {
                dfs(grid,x,y);
            }
        }
    }
};

四、字符串的排列

字符串的排列_牛客题霸_牛客网

其实就是有重复元素全排列

cpp 复制代码
int _n;
string path;
vector<string> ret;
bool check[11];
class Solution {
public:
    vector<string> Permutation(string str) {
        _n=str.size();
        sort(str.begin(),str.end());
        dfs(str);
        return ret;
    }
    void dfs(string str)
    {
        if(path.size()==_n)
        {
            ret.push_back(path);
            return;
        }
        for(int i=0;i<_n;++i)
        {
            if(!check[i])
            {
                if(i==0||str[i]!=str[i-1]||check[i-1])
                {
                    check[i]=true;
                    path.push_back(str[i]);
                    dfs(str);
                    path.pop_back();
                    check[i]=false;
                }
            }
        }
    }
};

五、N皇后

N皇后问题_牛客题霸_牛客网

题意要求特判

递归该层处理该行

cpp 复制代码
int _n;
bool Col[10],Dig1[20],Dig2[20];
int ret;
class Solution {
public:
    int Nqueen(int n) {
        _n=n;
        dfs(0);
        return ret;
    }
    void dfs(int row)
    {
        if(row==_n)
        {
            ++ret;
            return;
        }
        for(int col=0;col<_n;++col)
        {
            if(!Col[col]&&!Dig1[row-col+_n]&&!Dig2[row+col])
            {
                Col[col]=Dig1[row-col+_n]=Dig2[row+col]=true;
                dfs(row+1);
                Col[col]=Dig1[row-col+_n]=Dig2[row+col]=false;
            }
        }
    }
};

六、括号生成

括号生成_牛客题霸_牛客网

依旧是根据题目要求,写特殊判断

cpp 复制代码
int _n;
string path;
vector<string> ret;
class Solution {
public:
    vector<string> generateParenthesis(int n) {
        _n=n;
        dfs(0,0);
        return ret;
    }
    //dfs每层保证右括号数量<=左括号数量,并且二者数量都不能超过n
    void dfs(int LeftNum,int RightNum)
    {
        if(RightNum==_n)
        {
            ret.push_back(path);
            return;
        }
        if(LeftNum<_n)
        {
            path.push_back('(');
            dfs(LeftNum+1,RightNum);
            path.pop_back();
        }
        if(RightNum<LeftNum)
        {
            path.push_back(')');
            dfs(LeftNum,RightNum+1);
            path.pop_back();
        }
    }
};

七、矩阵最长递增路径

矩阵最长递增路径_牛客题霸_牛客网

dfs+记忆化搜索

cpp 复制代码
#include <vector>
int memo[1001][1001],dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int _m,_n,ret;
class Solution {
public:
    int solve(vector<vector<int> >& matrix) {
        _m=matrix.size(),_n=matrix[0].size();
        for(int i=0;i<_m;++i)
        {
            for(int j=0;j<_n;++j)
            {
                ret=max(ret,dfs(matrix,i,j));
            }
        }
        return ret;
    }
    int dfs(vector<vector<int>>&matrix,int i,int j)
    {
        if(memo[i][j])return memo[i][j];
        int path=1;
        for(int k=0;k<4;++k)
        {
            int x=i+dx[k],y=j+dy[k];
            if(x>=0&&x<_m&&y>=0&&y<_n&&matrix[x][y]>matrix[i][j])
            {
                path=max(path,dfs(matrix,x,y)+1);
            }
        }
        memo[i][j]=path;
        return path;
    }
};

此篇完。

最轻松的一个专栏,*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。

相关推荐
笨鸟笃行6 小时前
百日挑战——单词篇(第十二天)
学习
AA陈超6 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-31 映射标签到属性
c++·游戏·ue5·游戏引擎·虚幻
刃神太酷啦6 小时前
力扣校招算法通关:双指针技巧全场景拆解 —— 从数组操作到环检测的高效解题范式
java·c语言·数据结构·c++·算法·leetcode·职场和发展
**蓝桉**7 小时前
服务器管理
linux·笔记
西瓜树枝7 小时前
遗传算法与属性约简:原理、代码与参数配置
算法
lingggggaaaa7 小时前
小迪安全v2023学习笔记(一百四十三讲)—— Win系统权限提升篇&AD内网域控&NetLogon&ADCS&PAC&KDC&CVE漏洞
windows·笔记·学习·安全·内网安全·权限提升
haofafa7 小时前
STL之动态数组
开发语言·c++
jerryinwuhan7 小时前
理论及算法_时间抽取论文
前端·算法·easyui
71-37 小时前
牛客上的练习题——打印X形图案(有说明scanf返回值)
c语言·笔记·学习