IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 状态dfs/bfs+剪枝优化 -> 正文阅读

[数据结构与算法]状态dfs/bfs+剪枝优化

首先看状态dfs,题目是检查是否有合法括号字符串
在这里插入图片描述
在这里插入图片描述

  • 用c表示字符串的状态(平衡度):遇到左括号就+1,遇到右括号就-1,那么合法的字符串即为任意时刻 c ≥ 0 c≥0 c0且最后c=0
  • 从左上角到右下角,往右走m-1次,往下走n-1次因此路径长度是固定的,为(m-1)+(n-1)+1=m+n-1;极限的情况下左半边全为左括号,右半边全为右括号,因此c的最大值为(m+n-1)/2
  • 当遍历到(x,y)结点时,后面还剩下(m-1-x)+(n–1-y)+1=m-x+n-y-1,如果此时c大于这个值,后面就算全为右括号也不能使其变成0,直接返回false
  • 由于访问到最终结点后会直接返回,因此如果访问到已经访问过的结点,说明这个结点的这个状态是不能到达最终结点的最终状态的,可以直接返回false
  • 每次遍历之后更新c的值,直到访问到最终结点时c的值为1,说明找到了一条合法路径

代码如下:

int vis[105][105][105];
bool dfs(vector<vector<char>>& grid,int x,int y,int c){
    int m=grid.size();
    int n=grid[0].size();
    if(x==m-1&&y==n-1) return c==1; //访问到了右下角结点,判断c是否等于1
    if(c>m-x+n-y-2+1) return false; //剪枝,判断此节点能否合法的到达最终结点
    if(vis[x][y][c]) return false; //已经访问过的结点直接返回false
    vis[x][y][c]=1;
    if(grid[x][y]==')') c--; //更新c的值
    else c++;
    if(c<0) return false; //如果c小于0了直接返回false
    return (x<m-1&&dfs(grid,x+1,y,c))||(y<n-1&&dfs(grid,x,y+1,c)); //继续向右和下搜索
}
bool hasValidPath(vector<vector<char>>& grid) {
    int m=grid.size();
    int n=grid[0].size();
    if(grid[0][0]==')'||grid[m-1][n-1]=='(') return false;
    return dfs(grid,0,0,0);
}

状态bfs题目如下网格中的最短路径
在这里插入图片描述
在这里插入图片描述

  • 对于二维网格中的最短路问题,可以采用广度优先搜索的方法解决
  • 除了记录当前位置x,y,我们还记录还能消除障碍物的数量k,用三元组(x,y,rest)表示,对于当前状态,我们最多向四个方向进行搜索,设新的位置为(dx,dy),如果该位置为障碍物,新的三元组为(dx,dy,rest-1),否则为(dx,dy,rest),rest小于0的情况我们就不用去考虑,直接移除队列中
  • 由于广度优先搜索的特性,当我们第一次遍历到右下角且rest大于等于0的时候,说明我们就找到了一条最短的路径,返回记录的路径长度即可
  • 剪枝优化:我们可以发现从左上角到右下角的最短路中,最多只有(m+n-3)个障碍,且此最短路长度为(m+n-2),因此如果给定的k大于等于(m+n-3)的话,直接返回路径长度即可

代码如下:

int vis[45][45][90];
vector<vector<int>>dir={{-1,0},{1,0},{0,-1},{0,1}};
int shortestPath(vector<vector<int>>& grid, int k) {
    int m=grid.size();
    int n=grid[0].size();
    if(m==1&&n==1) return 0;
    queue<tuple<int,int,int>>q;
    q.emplace(0,0,k);
    if(k>=m+n-3) return m+n-2; //如果k大于此值的话,直接返回最短的路径
    vis[0][0][k]=1;
    int ans=0; //记录最短路径的长度
    while(q.size()>0){
        ans++;
        int len=q.size();
        for(int i=0;i<len;i++){
            auto [first,second,third]=q.front();
            q.pop();
            for(auto& d:dir){
                int dx=first+d[0];
                int dy=second+d[1];
                if(dx>=0&&dy>=0&&dx<m&&dy<n){ //新的位置在二维数组中,是否为障碍分开考虑
                    if(grid[dx][dy]==0&&!vis[dx][dy][third]){ 
                        if(dx==m-1&&dy==n-1) return ans; //到达终点返回路径长度
                        q.emplace(dx,dy,third);
                        vis[dx][dy][third]=1;
                    }
                    else if(grid[dx][dy]==1&&third-1>=0&&!vis[dx][dy][third-1]){
                        q.emplace(dx,dy,third-1);
                        vis[dx][dy][third-1]=1;
                    }
                }
            }
        }
    }
    return -1;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-11 16:39:00  更:2022-05-11 16:41:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:51:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码