leetCode刷题-图、回溯相关

news2025/2/8 1:54:50

岛屿数量

class Solution {
private:
    int mi;
    int mj;
public:
    int numIslands(vector<vector<char>>& grid) {
        mi = grid.size() - 1;    // i的范围 0~mi
        mj = grid[0].size() - 1; // j的范围 0~mj

        int landnum = 0;
        bool sea = false;
        do {
            pair<int, int> res = find_land(grid);
            if (res.first==-1&&res.second==-1)
                sea = true;
            else {
                landnum++;
                moveland(grid, res.first, res.second);
            }
        }while (!sea) ;
        return landnum;
    }

    pair<int, int> find_land(vector<vector<char>>& grid) {
        // 找到陆地返回坐标
        // 没找到返回-1,-1
        for (int i=0;i<mi+1;i++){
            for(int j=0;j<mj+1;j++){
                if(grid[i][j]=='1') {return make_pair(i,j);}
            }
        }
        return make_pair(-1,-1);
    }

    void moveland(vector<vector<char>>& grid, int i, int j) {
        // 将ij连通的全部土地变为水
        grid[i][j] = '0';

        if (i - 1 >= 0 && grid[i-1][j]=='1') {
            moveland(grid, i - 1, j);
        }
        if (j - 1 >= 0 && grid[i][j-1]=='1') {
            moveland(grid, i, j - 1);
        }
        if (j + 1 <= mj && grid[i][j+1]=='1') {
            moveland(grid, i, j + 1);
        }
        if (i + 1 <= mi && grid[i+1][j]=='1') {
            moveland(grid, i+1, j);
        }
        
        return;
    }
};

橘子腐烂(多源扩散,广度优先)

class Solution {
public:
    int orangesRotting(vector<vector<int>>& grid) {
        int min = 0;
        int res = 0;

        for(int i=0; i<grid.size();i++){
            for(int j=0; j<grid[0].size();j++){
                if(grid[i][j]==2){
                    res = bfs(grid,i,j,0);
                }
            }
        }

        //检查:如果为1
        int Max = -1;
        for(int i=0; i<grid.size();i++){
            for(int j=0; j<grid[0].size();j++){
                if(grid[i][j]==1){
                    res = -1;
                }
                if(Max < grid[i][j]) Max = grid[i][j];
            }
        }

        if(res!=-1) return max(Max-2, 0);
        else return -1;
    }

    int bfs(vector<vector<int>>& grid, int i, int j, int min){
        //起始点为:ij
        queue<pair<int,int>> bfs_q;
        int lay1 = 1;
        int lay2 = 0;
        int laynum = 1;
        bfs_q.push(make_pair(i,j));
        while(!bfs_q.empty()){
            //出队
            pair<int,int>point = bfs_q.front();
            bfs_q.pop();
            lay1--;//本层--
            //四个方向只要是好橘子就入队
            ///
            if(point.first-1>=0 && 
            (grid[point.first-1][point.second]==1 ||
            grid[point.first-1][point.second] > laynum+2)){
                grid[point.first-1][point.second]=laynum+2;//腐烂
                bfs_q.push(make_pair(point.first-1,point.second));
                lay2++;
            }
            if(point.second-1>=0 && 
            (grid[point.first][point.second-1]==1 ||
            grid[point.first][point.second-1] > laynum+2)){
                grid[point.first][point.second-1]=laynum+2;
                bfs_q.push(make_pair(point.first,point.second-1));
                lay2++;
            }
            if(point.first+1<=grid.size()-1 && 
            (grid[point.first+1][point.second]==1 ||
            grid[point.first+1][point.second] > laynum+2)){
                grid[point.first+1][point.second]=laynum+2;
                bfs_q.push(make_pair(point.first+1,point.second));
                lay2++;
            }
            if(point.second+1<=grid[0].size()-1 && 
            (grid[point.first][point.second+1]==1 ||
            grid[point.first][point.second+1] > laynum+2)){
                grid[point.first][point.second+1]=laynum+2;
                bfs_q.push(make_pair(point.first,point.second+1));
                lay2++;
            }
            ///
            if(lay1==0){
                laynum++;
                lay1 = lay2;
                lay2 = 0;
            }
        }

        return laynum-2;
    }

    void printgrid(vector<vector<int>>& grid){
        cout<<"打印图:"<<endl;
        for(int i=0; i<grid.size();i++){
            for(int j=0; j<grid[0].size();j++){
                cout<<grid[i][j]<<" ";
            }cout<<endl;
        }
    }
};

课程表(有向图、拓扑图、判断是否有环) 

全排列(插入法、回溯法)

class Solution {
public:
    vector<vector<int>> permute(vector<int>& nums) {
        //全排列
        queue<vector<int>>q_anss;
        vector<vector<int>>anss;
        // for(int num : nums){
        //     cout<<num;
        // }
        // cout<<endl;

        vector<int>ans = nums;
        if(nums.size()) q_anss.push(ans);
        int lay1 = 1;
        int lay2 = 0;

        for(int lay = 0; lay < nums.size(); lay++){//lay为确定下标为lay及其之前的元素
            // cout<<"进入外层循环(下面要固定的下标)lay = "<<lay<<endl;//下面要固定下标为lay
            while(lay1){  //在原有的解空间里改动【0~lay】已经确定
                //取出向量
                vector<int>out_vec = q_anss.front();
                // cout<<lay1<<"取出向量:";
                // for(int num:out_vec) cout<<num<<" ";
                // cout<<endl;
                q_anss.pop();
                lay1--;

                //加入向量
                for(int j=lay;j<nums.size();j++){
                    // cout<<"   把这个数放在前面(lay号位)"<<nums[j]<<"->index="<<lay<<endl;
                    vector<int> out_vec_copy = out_vec;
                    int temp=out_vec_copy[j];out_vec_copy[j]=out_vec_copy[lay];out_vec_copy[lay]=temp;
                    // cout<<"   操作后的新的数组为(并入队):";
                    // for(int num:out_vec_copy) cout<<num<<" ";
                    // cout<<endl;

                    q_anss.push(out_vec_copy);
                    lay2++;
                }
            }
            // cout<<"lay位置所有情况都已经固定(更新层)lay = "<<lay<<endl;
            // cout<<endl;
            //层更新
            if(lay1==0){
                lay1 = lay2;
                lay2 = 0;
            }
        }

        //将队列的内容放入向量中
        while(!q_anss.empty()){
            anss.push_back(q_anss.front());
            q_anss.pop();
        }


        return anss;
    }
};

全部子集【二进制法、增添法(类似回溯法)】

vector<vector<int>> subsets_1(vector<int>& nums){
    vector<vector<int>>anss;

    //构造
    vector<int>binary;
    for(int i=0;i<nums.size()+1;i++){
        binary.push_back(0);
    }

    //开始递增:所有情况
    while(!binary[0]){
        incrementBinary(binary);
        // printbinary(binary);
        vector<int> ans;
        for(int i=1;i<binary.size();i++){    
            if(binary[i]==1) ans.push_back(nums[i-1]);
        }
        anss.push_back(ans);
    }

    return anss;
}

void incrementBinary(std::vector<int>& binary) {
    int n = binary.size();
    for (int i = n - 1; i >= 0; --i) {
        if (binary[i] == 0) {
            binary[i] = 1;
            return;
        } else {
            binary[i] = 0;
        }
    }
}

void printbinary(std::vector<int>& binary) {
    for(int k=0;k<binary.size();k++) cout<<binary[k];
    cout<<endl;
}

 树的层序遍历:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>>anss_index;
        queue<vector<int>>q_IdxSet;
        vector<int>ans;
        ans.push_back(-1);
        q_IdxSet.push(ans);
        anss_index.push_back(ans);
        int lay1 = 1;
        int lay2 = 0;
        for(int lay=0;lay<nums.size();lay++){
            while(lay1){//本层还有的话就一直取
                //取
                vector<int>ans_out = q_IdxSet.front();
                q_IdxSet.pop();
                lay1--;
                //根据取的存:从最大的下标开始
                for(int k=1+ans_out.back();k<nums.size();k++){
                    vector<int>ans_in = ans_out;//复制一份再添加
                    ans_in.push_back(k);
                    q_IdxSet.push(ans_in);
                    anss_index.push_back(ans_in);
                    lay2++;
                }
            }
            if(lay1==0){
                lay1 = lay2;
                lay2 = 0;
            }
        }
        vector<vector<int>>anss;
        for(int i=0;i<anss_index.size();i++){
            vector<int>ans;
            for(int j=0;j<anss_index[i].size();j++){
                if(anss_index[i][j]!=-1) ans.push_back(nums[anss_index[i][j]]);
            }
            anss.push_back(ans);
        }
        return anss;
    }
};

9键打字(还是和上面的解法一样)

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        vector<string>ans;
        vector<vector<char>>keyboard;
        keyboard.push_back({});
        keyboard.push_back({});
        keyboard.push_back({'a','b','c'});
        keyboard.push_back({'d','e','f'});
        keyboard.push_back({'g','h','i'});
        keyboard.push_back({'j','k','l'});
        keyboard.push_back({'m','n','o'});
        keyboard.push_back({'p','q','r','s'});
        keyboard.push_back({'t','u','v'});
        keyboard.push_back({'w','x','y','z'});
        //开始层序遍历解空间
        queue<string> q;
        q.push("");
        int lay1 = 1;
        int lay2 = 0;
        for(int lay=0;lay<digits.size();lay++){
            while(lay1){
                //先取
                string out_string = q.front();
                q.pop();
                lay1--;
                //再存
                for(int j = 0;j<keyboard[int(digits[lay])-48].size();j++){
                    string in_string = out_string;
                    in_string+=keyboard[int(digits[lay])-48][j];
                    q.push(in_string);
                    lay2++;
                }
            }
            if(lay1==0){
                lay1 = lay2;
                lay2 = 0;
            }
        }
        //将q转为ans
        while(!q.empty()){
            if(q.front()!="")ans.push_back(q.front());
            q.pop();
        }
        return ans;
    }
};

单词搜索【递归、空间超过】

class Solution {
private:
    bool ans;
public:
    bool exist(vector<vector<char>>& board, string word) {
        ans = false;
        for(int i=0;i<board.size();i++){
            for(int j=0;j<board[0].size();j++){
                if(board[i][j]==word[0]) {
                    map<string,bool>trace_m;
                    dfs(board,word,i,j,0,trace_m);
                }
            }
        }
        return ans;
    }

    void dfs(vector<vector<char>>& board, string word, int i, int j, int idx , map<string,bool> trace_m){
        //越界
        if(i<0 || j<0 || i>=board.size() || j>=board[0].size()) return;
        if(idx==word.size())return;
        //字母不符合
        if(board[i][j]!=word[idx]) return;
        //解决回头文
        string add = to_string(i) + to_string(j);
        if(trace_m.count(add) && trace_m[add])return;
        trace_m[add] = true;
        if(idx==word.size()-1){
            ans = true; 
            return;
        }
        dfs(board,word,i-1,j,idx+1,trace_m);
        dfs(board,word,i+1,j,idx+1,trace_m);
        dfs(board,word,i,j+1,idx+1,trace_m);
        dfs(board,word,i,j-1,idx+1,trace_m);
    }
};


//题解给的
class Solution {
public:
    //visited是原件传入,k为下标
    //check(board, visited, i, j, word, 0);
    bool check(vector<vector<char>>& board, vector<vector<int>>& visited, int i, int j, string& s, int k) {
        if (board[i][j] != s[k]) { //模式匹配失败
            return false;
        } else if (k == s.length() - 1) { //越界
            return true;
        }
        //模式匹配成功+不越界
        visited[i][j] = true;//标记
        vector<pair<int, int>> directions{
  
  {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
        bool result = false;

        for (const auto& dir: directions) {//dir表示四个方向
            int newi = i + dir.first, newj = j + dir.second;//新坐标
            if (newi >= 0 && newi < board.size() && newj >= 0 && newj < board[0].size()) {//没有越界
                if (!visited[newi][newj]) {//没被访问过
                    //
                    bool flag = check(board, visited, newi, newj, s, k + 1);
                    if (flag) {
                        result = true;
                        break;
                    }
                    //
                }
            }
        }
        visited[i][j] = false;
        return result;
    }

    bool exist(vector<vector<char>>& board, string word) {
        int h = board.size(), w = board[0].size();
        vector<vector<int>> visited(h, vector<int>(w));  //初始化二维数组
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) { //每个地方都调用check
                bool flag = check(board, visited, i, j, word, 0);//每次从头遍历都用一个新的visit
                if (flag) {
                    return true;
                }
            }
        }
        return false;
    }
};

N皇后(广度优先)

class Solution {
    vector<vector<string>> ans;
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<string> CB = initChess(n);
        //广度优先算法
        queue<vector<string>> q_CB;
        q_CB.push(CB);
        int lay1 = 1;
        int lay2 = 0;
        for(int lay = 0; lay<n; lay++){
            while(lay1){
                //取棋盘
                vector<string> CB_out = q_CB.front();
                q_CB.pop();
                lay1--;
                //生成新棋盘(条件:CB_out是活棋)
                if(!isDied(CB_out,lay)){
                    //遍历这一行,只要是0就可以下Q
                    for(int j = 0; j < n; j++){
                        if(CB_out[lay][j] == '0'){
                            vector<string> CB_in = writeQ(CB_out,lay,j);
                            q_CB.push(CB_in);
                            lay2++;
                            //判断是否是最终结果
                            if(lay==n-1 && isSuccess(CB_in)){
                                ans.push_back(CB_in);
                            }
                        }
                    }//只要是0就可以下Q
                }
            }//while(lay1){
            if(lay1==0){
                lay1 = lay2;
                lay2 = 0;
            }
        }
        return ans;
    }

    vector<string> initChess(int n){
        string row = "";
        for(int i=0;i<n;i++){
            row+="0";
        }
        // cout<<row;
        vector<string> chessB;
        for(int i=0;i<n;i++){
            chessB.push_back(row);
        }
        return chessB;
    }

    void printChess(vector<string>cB){
        cout<<"打印棋盘"<<endl;
        for(int i=0;i<cB.size();i++){
            cout<<cB[i]<<endl;
        }
        cout<<endl;
    }

    bool isDied(vector<string>& CB,int row){
        //看看第row行是否都是“.”
        int pointnum = 0;
        for(int i=0;i<CB.size(); i++){
            if(CB[row][i] == '.') pointnum++;
        }
        if(pointnum == CB.size()) return true;
        else return false;
    }

    bool isSuccess(vector<string>& CB){
        //看看第-1行是否有n-1个“.”
        int pointnum = 0;
        for(int i=0;i<CB.size(); i++){
            if(CB[CB.size()-1][i] == '.') pointnum++;
        }
        if(pointnum == CB.size()-1) return true;
        else return false;
    }

    //下棋
    //vector<string> CB_in = writeQ(CB_out,lay,j);
    vector<string> writeQ(vector<string>CB, int row, int j){
        //横向
        for(int i=0;i<CB.size();i++){
            CB[row][i] = '.';
        }
        for(int i=0;i<CB.size();i++){
            CB[i][j] = '.';
        }
        CB[row][j] = 'Q';
        //斜向
        for(int i = row+1;i<CB.size();i++){
            if(j-i+row >=0 && j-i+row<=CB.size()-1) CB[i][j-i+row] = '.';
            if(j+i-row >=0 && j+i-row<=CB.size()-1) CB[i][j+i-row] = '.';
        }
        return CB;

    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2294554.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows编程:下载与安装 Visual Studio 2010

本节前言 在写作本节的时候&#xff0c;本来呢&#xff0c;我正在写的专栏&#xff0c;是 MFC 专栏。而 VS2010 和 VS2019&#xff0c;正是 MFC 学习与开发中&#xff0c;可以使用的两款软件。然而呢&#xff0c;如果你去学习 Windows API 知识的话&#xff0c;那么&#xff0…

OpenEuler学习笔记(十八):搭建企业云盘服务

要在 OpenEuler 上搭建企业云盘&#xff0c;可借助一些开源软件来实现&#xff0c;以下以 Nextcloud 为例详细介绍搭建步骤。Nextcloud 是一款功能丰富的开源云存储解决方案&#xff0c;支持文件共享、同步、协作等多种功能。 1. 系统环境准备 确保 OpenEuler 系统已更新到最…

什么是三层交换技术?与二层有什么区别?

什么是三层交换技术&#xff1f;让你的网络飞起来&#xff01; 一. 什么是三层交换技术&#xff1f;二. 工作原理三. 优点四. 应用场景五. 总结 前言 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 大家好…

Ollama+deepseek+Docker+Open WebUI实现与AI聊天

1、下载并安装Ollama 官方网址&#xff1a;Ollama 安装好后&#xff0c;在命令行输入&#xff0c; ollama --version 返回以下信息&#xff0c;则表明安装成功&#xff0c; 2、 下载AI大模型 这里以deepseek-r1:1.5b模型为例&#xff0c; 在命令行中&#xff0c;执行&…

Linux生成自签证书【Nginx】

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;CSDN博客专家   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01…

网络安全 | 加密技术揭秘:保护数据隐私的核心

网络安全 | 加密技术揭秘&#xff1a;保护数据隐私的核心 一、前言二、对称加密技术2.1 原理2.2 优点2.3 缺点2.4 应用场景 三、非对称加密技术3.1 原理3.2 优点3.3 缺点3.4 应用场景 四、哈希函数4.1 原理4.2 优点4.3 缺点4.4 应用场景 五、数字签名5.1 原理5.2 优点5.3 缺点5…

使用服务器部署DeepSeek-R1模型【详细版】

文章目录 引言deepseek-r1IDE或者终端工具算力平台体验deepseek-r1模型总结 引言 在现代的机器学习和深度学习应用中&#xff0c;模型部署和服务化是每个开发者面临的重要任务。无论是用于智能推荐、自然语言处理还是图像识别&#xff0c;如何高效、稳定地将深度学习模型部署到…

DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区

Direct3D 11 总结 —— 4 绘制三角形_direct绘制三角形-CSDN博客 DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区 - X_Jun - 博客园 练习题 粗体字为自定义题目 尝试交换三角形第一个和第三个顶点的数据&#xff0c;屏幕将显示什么&#xff1f;为什么&…

第二次连接k8s平台注意事项

第二次重新打开集群平台 1.三台机子要在VMware打开 2.MobaBXterm连接Session 3.三个机子docker重启 systemctl restart docker4.主节点进行平台链接 docker pull kubeoperator/kubepi-server[rootnode1 home]# docker pull kubeoperator/kubepi-server [rootnode1 home]# # 运…

Mybatis篇

1&#xff0c;什么是Mybatis &#xff08; 1 &#xff09;Mybatis 是一个半 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;它内部封装了 JDBC&#xff0c;开发时只需要关注 SQL 语句本身&#xff0c;不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁…

三维粒子滤波(Particle Filter)MATLAB例程,估计三维空间中匀速运动目标的位置(x, y, z),提供下载链接

三维粒子滤波(Particle Filter)MATLAB例程,估计三维空间中匀速运动目标的位置(x, y, z) 文章目录 介绍功能运行结果代码介绍 本 MATLAB 代码实现了三维粒子滤波( P a r t i c l e F i l t e

设计模式Python版 享元模式

文章目录 前言一、享元模式二、享元模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间的组合&…

从0开始,来看看怎么去linux排查Java程序故障

一&#xff0c;前提准备 最基本前提&#xff1a;你需要有liunx环境&#xff0c;如果没有请参考其它文献在自己得到local建立一个虚拟机去进行测试。 有了虚拟机之后&#xff0c;你还需要安装jdk和配置环境变量 1. 安装JDK&#xff08;以OpenJDK 17为例&#xff09; 下载JDK…

【MySQL】centos 7 忘记数据库密码

vim /etc/my.cnf文件&#xff1b; 在[mysqld]后添加skip-grant-tables&#xff08;登录时跳过权限检查&#xff09; 重启MySQL服务&#xff1a;sudo systemctl restart mysqld 登录mysql&#xff0c;输入mysql –uroot –p&#xff1b;直接回车&#xff08;Enter&#xff09; 输…

区块链项目孵化与包装设计:从概念到市场的全流程指南

区块链技术的快速发展催生了大量创新项目&#xff0c;但如何将一个区块链项目从概念孵化成市场认可的产品&#xff0c;是许多团队面临的挑战。本文将从孵化策略、包装设计和市场落地三个维度&#xff0c;为你解析区块链项目成功的关键步骤。 一、区块链项目孵化的核心要素 明确…

【数据科学】一个强大的金融数据接口库:AKShare

文章目录 1. AKShare 简介2. 安装 AKShare3. AKShare 核心功能3.1 获取股票数据3.2 获取股票实时数据3.3 获取基金数据3.4 获取期货数据3.5 获取外汇数据3.6 获取数字货币数据 4. 数据处理与存储5. 实战案例6. 总结 AKShare 是一个开源的金融数据接口库&#xff0c;它提供了简单…

Ubuntu 22.04系统安装部署Kubernetes v1.29.13集群

Ubuntu 22.04系统安装部署Kubernetes v1.29.13集群 简介Kubernetes 的工作流程概述Kubernetes v1.29.13 版本Ubuntu 22.04 系统安装部署 Kubernetes v1.29.13 集群 1 环境准备1.1 集群IP规划1.2 初始化步骤&#xff08;各个节点都需执行&#xff09;1.2.1 主机名与IP地址解析1.…

Java项目: 基于SpringBoot+mybatis+maven+mysql实现的智能学习平台管理系(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismavenmysql实现的智能学习平台管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、…

【Gitlab】虚拟机硬盘文件丢失,通过xx-flat.vmdk恢复方法

前言 由于近期过年回家&#xff0c;为了用电安全直接手动关闭了所有的电源&#xff0c;导致年后回来商上电开机后exsi上的虚拟机出现了问题。显示我的gitlab虚拟机异常。 恢复 开机之后虚拟机异常&#xff0c;通过磁盘浏览发现gitlab服务器下面的虚拟机磁盘文件只有一个xxx-f…

GC日志的解读

GC日志的解读 gc日志的解读 gc日志的解读