算法
(DFS) $O(n^23^k)$
在深度优先搜索中,最重要的就是考虑好搜索顺序。
我们先枚举单词的起点,然后依次枚举单词的每个字母。
过程中需要将已经使用过的字母改成一个特殊字母,以避免重复使用字符。
时间复杂度分析:单词起点一共有 $n^2$ 个,单词的每个字母一共有上下左右四个方向可以选择,但由于不能走回头路,所以除了单词首字母外,仅有三种选择。所以总时间复杂度是 $O(n^23^k)$。
C++ 代码
class Solution {
public:
bool hasPath(vector<vector<char>>& matrix, string str) {
for (int i = 0; i < matrix.size(); i ++ )
for (int j = 0; j < matrix[i].size(); j ++ )
if (dfs(matrix, str, 0, i, j))
return true;
return false;
}
bool dfs(vector<vector<char>> &matrix, string &str, int u, int x, int y) {
if (matrix[x][y] != str[u]) return false;
if (u == str.size() - 1) return true;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
char t = matrix[x][y];
matrix[x][y] = '*';
for (int i = 0; i < 4; i ++ ) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < matrix.size() && b >= 0 && b < matrix[a].size()) {
if (dfs(matrix, str, u + 1, a, b)) return true;
}
}
matrix[x][y] = t;
return false;
}
};
## 想不到
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};这一句是啥意思呀
代表上下左右移动,dx的-1代表向左移动,1代表向右移动。dy的-1代表向上移动,1代表向下移动
没想到用特殊字符替代的这种方法,学到了,习惯性开visited数组浪费了好多空间。
请问换成错误代码那两行之后错在哪了? 过了15个样例
你好,我的理解是这个例子
str=a
martix=[a]
第一步成功了,但是在继续dfs的时候是不能继续dfs的,因为
if (nx < 0 || nx >= n || ny < 0 || ny >= m || st[nx][ny]) continue;
下标全都越界,进入continue
,没法进入预计的dfs(1)请问大佬们,这个哪里出错了 只不过是用x=x+dx[i],y=y+dy[i];就出错了,是产生歧义了吗,还是这个会改变x的值,求大佬解答Orz
class Solution {
public:
vector[HTML_REMOVED]path;
bool hasPath(vector[HTML_REMOVED]>& matrix, string &str) {
for( int i=0;i[HTML_REMOVED]>& matrix, string &str,int x,int y,int u)
{
if(matrix[x][y]!=str[u]) return false;
if(u==str.size()-1) return true;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
char ch=matrix[x][y];
matrix[x][y]=’*’;
for(int i=0;i<4;i++)
{
x=x+dx[i];y=y+dy[i];
if(x>=0&&x[HTML_REMOVED]=0&&y<matrix[x].size())
{
if(dfs(matrix,str,x,y,u+1)) return true;
}
}
matrix[x][y]=ch;
return false;
}
};
改变x、y的值了,恢复现场的时候会改变matrix其他位置的值
大佬们,请问这个是哪里出错呢
class Solution {
public:
int curi,curj;
int dpi[4]={0,0,1,-1};
int dpj[4]={1,-1,0,0};
int a[907][907];
bool hasPath(vector[HTML_REMOVED]>& matrix, string &str) {
memset(a,0,sizeof(a));
int n=matrix.size();
if(n==0)
return false;
int m=matrix[0].size();
int i,j;
int p=0;
for(i=0;i[HTML_REMOVED]> &m,string &s,int sum)
{
if(sum==s.size())
return true;
if(curi<0||curj<0||curi>=m.size()||curj>=m[0].size()||(m[curi][curj]!=s[sum]&&sum[HTML_REMOVED]=0&&curj>=0&&curi<m.size()&&curj<m[0].size()&&m[curi][curj]==s[sum]&&sum<s.size())
return dfs(curi+dpi[0],curj+dpj[0],m,s,sum)||dfs(curi+dpi[1],curj+dpj[1],m,s,sum)||dfs(curi+dpi[2],curj+dpj[2],m,s,sum)||dfs(curi+dpi[3],curj+dpj[3],m,s,sum);
}
};
想知道n²3^k那个k是怎么打上去的TAT
$O(n^23^k)$
$(n^23^k)$
哇 谢谢!
matrix[x][y] = t;这一步感觉没啥用吧
恢复现场吧,这是传的引用,matrix的值被修改了,如果不恢复的话不然下一次dfs的时候就会有问题
恢复现场,保证在搜索一条路径时一个字母只用一次
这个题的思路和蛇形矩阵好像啊
这个为什么会段错误呢qaq
错误数据是二维数组为空
这句会先执行
matrix[0].size()==0
,对空数组取下标为0的元素就越界了。可以改为第一个条件为true就不会执行第二个语句了
666
if (matrix[x][y] != str[u]) return false; if (u == str.size() - 1) return true;
请问有大佬能解释一下这两行是什么意思吗?
第一个if是指当前字符串不匹配直接返回false
第二个if是指当第当前字符匹配且当前为最后一个字符时,直接返回true
明白了~谢谢!
谢谢!
而且这两行顺序还不能换
避免最后一个u不同的情况
感谢
大佬,为什么这两行的顺序不能换呢?
我 y 总写的代码好骚啊!
y总,用来保存matrix[x][y]值的临时变量t是不是可以不用定义?因为程序进行到了这里,matrix[x][y]==str[u]是成立的,还原matrix[x][y]的时候直接用str[u]是不是就可以啦
可以的。
定义的变量好多,看混淆了都
这题变量不多呀hh
您好,请问您一下为什么这个方法在LeetCode上运行,会显示 当输入是[[“a”]]”ab” 时,会输出true
已找到问题所在,谢谢啦~
好滴
为什么这一种写法是 cur.size() == index, 而上面这种是cur.size() - 1 == index
都是可以的。
y总,貌似这两句交换顺序,就通过不了了
最后一个位置没有判断是否相同就直接返回true,肯定不对啊。
而且第一行u一定不会越界
yls,为什么上面的可以过,下面的就错了呢?
if (n == str.size())
和if (n == str.size() - 1)
不等价。另外调试代码要学会用printf
大法,这样学起来会快一些。请问OJ上也能用printf吗?
能用,没问题。
但是在下面那种方式中,运行到if (n == str.size())时,所有的字符都已匹配完,所以应该也没问题才对啊,这里不太明白。。
是不是因为这样:
虽然n个字符已经匹配完成,但没有return退出当前函数的话,会继续执行下面的代码,那么在当前函数里,会以n为起点继续去搜索,所以出了问题。
当输入是
[["a"]], "a"
时下面的写法会返回false
。下面的写法,如果输入是单字符,就进不去for循环然后直接返回false
能进去for循环,但是进不去for循环里边的第一个if判断,因为单个字符无论向哪个方向移动,都会超出边界,所以四个方向搜索完以后,最后输出false
嗯
对滴。
虽然能理解,但还是让人心情失落,又不能说玄学
如果测试数据为[[“A”]] “A”,按照上述程序会输出false啊,因为进不去for循环中的if语句
我运行了一遍,会输出
true
。它应该是在if(u == str.length() - 1) return true;时就返回了true的