当前位置:首页 » 《休闲阅读》 » 正文

DFS和BFS的上下左右搜索问题(递归和迭代)

20 人参与  2024年10月20日 09:20  分类 : 《休闲阅读》  评论

点击全文阅读


目录

一·题目(单词搜索问题):

二·思路解释:

三·解答代码:

​编辑   

四·题目(腐烂的苹果):

五·思路解释:

六·解答代码:   

             ​​​​


477562ae040f49c39948807a197ef759.png

 

一·题目(单词搜索问题):

daf02e10e3554a5da3f122efedf46945.jpeg

 

7474ce7f99424a089c78a79bb071a5ca.png

newcode题目链接: 单词搜索_牛客题霸_牛客网

二·思路解释:

 

c5218780ad3c48fe8ab7d079e7d9628d.jpeg

思路:个人理解是找到word中的第一个元素,然后去递归的上下左右查找,最后根据word的下标变化等看是否返回true

下面具体说一下个人思路(也是根据大佬悟出来的):这里有点明显想考的是递归的使用,这里为了方便记录遍历到原数组位置

以及防止查找时候查到已经找到的原数组中元素(word中有连续重复元素在board中出现)等,因此不方便在原数组里面操作,因此重新建一个二维数组(这里个人称作真假表->主要记录遍历原数组找到元素位置,给它在真假表中用true标记,而默认是false,这里标记它的路径也能防止“走重的操作了”).

因此这里首先建立一个递归函数,首先要想完成这个操作需要哪些参数等呢? word和它的索引 ,board和它的下标i,j,以及我们的真假表(这里下标直接用board的i,j即可);

一开始先遍历原数组找到word首元素的位置,从它开始进行递归(当然这里有种特殊情况,下面会讲到)

 

1·首先不是递归嘛:然后先找递归终止条件这里可以根据遍历上下左右的时候出现的越界问题,总结了四个返回false的情况,根据后面的查找操作也不难找出另两个即可能出现查找了曾经找的元素+不是word中对应下标所指向的元素。-->这里就得到了递归不成立的六大终止条件。   如果我们根据实例1试到最后一次对归还会发现最后一次如果再次遍历,它应该设置一个返回真的条件 ,于是就得到了另一个返回真的条件--->也就是当word索引越界的情况

 

2·也就是如何递归,这里如果上面没有被返回也就是到了下面也就是找到了,因此可以在真假表对应映射位置填入true,然后接着往它左右递归即可,最后呢根据递归完往回溯可以看出这里最后返回的上下左右的bool类型值应该是或的关系。

3·这里可以考虑给真假表对应的当时填入true位置复原成false(当然这里对本题解无关系)

042f42b7a4b84f5da67d844d5d8eb035.png

这里有一个细节问题;也就是上面说的,这里找到对应word[0],我们就返回这个递归函数,这里是错误的(表示掉过坑),这里可能是这种情况:["CAA","AAA","BCD"] "AAB"-->这里如果找到第一个A,然后递归下去最后返回的一定是false,然而此例子返回的应该是true,因此如果它是false就接着遍历board继续找,然后再次递归, 因此这里如果递归函数返回false不一定题解真实false,但是如果返回true则题解一定是true。,因此注意好这个基本到这就没什么问题了。

 

 

下面画图以实例1为例子解释如何递归的:

f4e7d13964904687ac06318dea440af1.jpeg

 

 c8529f5eef584af68ffa76c36165084d.png

0e80e88904904527ac2a44dfda57808c.jpeg

 

 

三·解答代码:

0c77258c60734486918e06376cb50648.gif         172cfa1191df4e76a1df166c5a7cd0c0.jpeg    72628a2e70f14658a546cc7a26e2c327.jpeg     

 

class Solution {public:    /**     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可     *     *      * @param board string字符串vector      * @param word string字符串      * @return bool布尔型     */     bool recursion_find(vector<string>& board,int i,int j, string word,int word_index,vector<vector<bool>>TF_graph){        if(word_index==word.size()) return true;         if(i<0||i>=board.size()||j<0||j>=board[0].size()||TF_graph[i][j]==true||board[i][j]!=word[word_index]) return false;                  TF_graph[i][j]=true;         bool target_on=recursion_find(board,i-1,j,word,word_index+1,TF_graph);         bool target_under=recursion_find(board,i+1,j,word,word_index+1,TF_graph);         bool target_left=recursion_find(board,i,j-1,word,word_index+1,TF_graph);         bool target_right=recursion_find(board,i,j+1,word,word_index+1,TF_graph);         // TF_graph[i][j]=false;         return  target_on||target_under||target_left|| target_right;                 }    bool exist(vector<string>& board, string word) {         int m=board.size();         int n=board[0].size();         vector<vector<bool>>TF_graph(m,vector<bool>(n,false));         for(int i=0;i<m;i++){            for(int j=0;j<n;j++){                if(board[i][j]==word[0]){                    //return recursion_find(board,i,j,word,0,TF_graph);                   if (recursion_find(board,i,j,word,0,TF_graph)) {                        return true;                    }                }                            }         }         return false;    }};

af8d4d85da184b02a0e92779b159d1ba.jpeg   

四·题目(腐烂的苹果):

3a0b232d9d74479484a603119eb714c0.png

nowcoder题目链接:腐烂的苹果_牛客题霸_牛客网 

五·思路解释:

 

思路:这里虽然是bfs有两种思路的方向可以让我们完成代码的操作,一个就是递归,另一个就是迭代,这里考虑一下迭代完成,

即通过选择合容器配合出入以及循环完成。下面讲解一下迭代应用于本题的具体思路:

1·首先这道题就是我们先遍历数组然后找到所有的2,之后在同时从每个2开始上下左右找1覆盖成2并记录位置,并把它们就录下来方便下次用,第一批2用完后,这时是过去了一分钟故用个计时器记录一下,然后拿到刚刚保存的那些2重复操作即可,最后呢要么里面还有1没有被修改要么就是2和0了,这里如果有1那么就返回-1,否则返回这个计时器记录的就可。

 

2·思路的进一步转化:由上面的思路,如保存一些2的位置然后后面还要添加方便再一次使用,很容易想到队列,这里还有两个要处理

如何控制它每次都是用完保存的第一批然后再用第二批,那么此时可以用一个size记录第一批长度然后再入第二批,依次对size减减,另一个就是什么时候开始计时? 根据题意我们可以知道每次的同一批2是同时查找的故这就是一分钟,因此一批过后才计数器加加。

 042f42b7a4b84f5da67d844d5d8eb035.png

 

当然这里还有一个更细节问题需要处理就是我们的计时器:先说结论这里计时器count,如果找不到1,那么应该返回的是cout-1;为什么呢?这里不是,每次队列里每减完一批2所在位置那么count就加加,我们可以根据例1推算出,结论:当走到最后的那批,此时这批是无法找到再下一批的但是还会使得count++,故这次应该不算,但是我们把它算进去了,故应该减去。

 

 

下面画图解释一下: 

1a03ad2479ab4904bf35918f15b5e949.png

 

 

六·解答代码:   

class Solution {public:    /**     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可     *     *      * @param grid int整型vector<vector<>>      * @return int整型     */     queue<pair<int,int>>q;     int count=0;//这里写一个函数判断下标是否越界问题:       bool judge(vector<vector<int> >& grid,int m,int n){       if (m<0||m>=grid.size()||n<0||n>=grid[0].size()) return false;       else return true;             }      //子函数利用容器特点把递归转换成迭代解决:         void bfs(vector<vector<int> >& grid,int &count){                       while(!q.empty()){            int size=q.size();            while(size--){                pair<int,int> f=q.front();                q.pop();                int i=f.first;                int j=f.second;                if(judge(grid,i,j-1)&&grid[i][j-1]==1){                     q.push(make_pair(i,j-1));                     grid[i][j-1]=2;                }                if(judge(grid,i,j+1)&&grid[i][j+1]==1){                     q.push(make_pair(i,j+1));                     grid[i][j+1]=2;                }                if(judge(grid,i-1,j)&&grid[i-1][j]==1){                     q.push(make_pair(i-1,j));                     grid[i-1][j]=2;                }                if(judge(grid,i+1,j)&&grid[i+1][j]==1){                     q.push(make_pair(i+1,j));                     grid[i+1][j]=2;                }            }                     count++;           }     }    int rotApple(vector<vector<int> >& grid) {        // write code here             for(int i=0;i<grid.size();i++){                for(int j=0;j<grid[0].size();j++){                    if(grid[i][j]==2){                        q.push(make_pair(i,j));                    }                                    }             }             bfs(grid,count);             for(int i=0;i<grid.size();i++){                for(int j=0;j<grid[0].size();j++){                    if(grid[i][j]==1) return -1;                                                                                }             }             return count-1;                 }};

             ​​​​

 若有补充希望大佬们留言.        

 


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/174437.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1