找出矩阵中最长路径的长度,其中包含连续字符及其路径
Posted
技术标签:
【中文标题】找出矩阵中最长路径的长度,其中包含连续字符及其路径【英文标题】:Find the length of the longest path in the matrix with the consecutive character along with its path 【发布时间】:2020-01-18 13:51:06 【问题描述】:给定 M * N 个字符矩阵,找出从给定源开始的矩阵中最长路径的长度。
注意:最长路径中的所有字符都应该增加并且 按字母顺序相互连续。我们是 允许在所有 8 个方向搜索下一个字符。
我已经正确地找出了序列的长度,但是路径有问题。路径不正确。 这是我的代码
#include<iostream>
#include<vector>
using namespace std;
//Below array details all 8 posible directions
int row[] = -1,-1,-1, 0, 0, 1, 1, 1 ;
int col[] = 1, 0, -1, 1,-1, -1,0, 1 ;
int length(char arr[][5], int x, int y, char previous, vector<pair<int,int> > &path, int k)
// x and y must be bounded between 0 to 4
if( x < 0 || x > 4 || y > 4 || y < 0)
return 0;
int l = 0;
int max_length = 0;
for( int i = 0; i < 8; i++)
// storing next character in search
char ch = arr[x+row[i]][y+col[i]];
//checking whether ch is the next character in the sequence or not
if(ch == previous + 1)
//if k != path.size() then we have taken back in
// the sequence so no need to push back character in the path
if(k == path.size())
// Pushing co-ordinates of next valid character
path.push_back(make_pair(x+row[i], y+col[i]));
else
path.pop_back();
l = 1 + length(arr, x+row[i], y+ col[i], ch , path, ++k);
max_length = max( l, max_length);
return max_length;
int main()
char arr[5][5] =
'd','e','h','x','b',
'a','o','g','p','e',
'd','d','c','f','d',
'e','b','e','a','s',
'c','d','y','e','n'
;
vector<pair<int,int> > path;
//Pusing source address
path.push_back(make_pair(2,2));
int k = 1;
int Len = length(arr, 2, 2 , arr[2][2], path, k);
cout << "Length of the Longest sequence is : " << Len + 1 <<endl;
//printing the path
cout << "Path is : "<<endl;
for( pair<int,int> i : path)
cout <<"( " << i.first <<","<<i.second <<" )" ;
return 0;
实际输出:
最长序列的长度为:6 路径是 ( 2,2 )( 2,1)( 3,0 )( 3,2 )( 2,3 )( 1,2 )( 0,2 )
预期输出
最长序列的长度为:6 路径是 ( 2,2 )(2,1 )( 3,2 )( 2,3 )( 1,2 )( 0,2 )
我的输出中有一个额外的 (3,0)。当我从 (3,0) 取回时,我无法弹出它。 任何帮助将不胜感激。
【问题讨论】:
(3,0)
来自哪里?您是否尝试使用调试器逐行执行代码?
【参考方案1】:
构建路径的算法不能这样工作。回溯时你有一些预知不破坏路径,但是当回溯之后——搜索再次向另一个方向加深时,路径将成为两条路径的组合:前一个分支不会从中删除。
所以在你的实际情况下,第一次尝试是从 (2,1) 到 (3,0)。在那里它发现它不能再深入了,但它是迄今为止最好的路径。然后它回溯到(2,1)。路径没有缩短(因为它仍然是最好的)。然后搜索再次加深到 (3,2)。然后将该地址添加到路径中,从而使其不一致。
它不能那样工作。当你找到一条更好的路径时,你需要创建一条新路径,并确保它永远不会再被改变。只有当你找到更好的路径时,你才完全替换它。
我还建议限制函数的参数(++k
也是一个问题——但我们可以不这样做)。让函数返回最长的路径,而不是改变路径参数。长度总是可以从中推导出来的。
所以这里是你的函数可以如何修改:
#include<iostream>
#include<vector>
using namespace std;
//Below array details all 8 posible directions
int row[] = -1,-1,-1, 0, 0, 1, 1, 1 ;
int col[] = 1, 0, -1, 1,-1, -1,0, 1 ;
vector<pair<int,int> > longestPath(char arr[][5], int x, int y)
char previous = arr[x][y];
vector<pair<int,int> > path; // a new(!) path
// x and y must be bounded between 0 to 4
if( x < 0 || x > 4 || y > 4 || y < 0)
return path;
for (int i = 0; i < 8; i++)
// storing next character in search
char ch = arr[x+row[i]][y+col[i]];
//checking whether ch is the next character in the sequence or not
if(ch == previous + 1)
vector<pair<int,int> > foundPath = longestPath(arr, x+row[i], y+ col[i]);
if (foundPath.size() > path.size())
path = foundPath;
path.insert(path.begin(), make_pair(x,y));
return path;
int main()
char arr[5][5] =
'd','e','h','x','b',
'a','o','g','p','e',
'd','d','c','f','d',
'e','b','e','a','s',
'c','d','y','e','n'
;
vector<pair<int,int> > path = longestPath(arr, 2, 2);
//printing the path
cout << "Path is : "<<endl;
for( pair<int,int> i : path)
cout <<"( " << i.first <<","<<i.second <<" )" ;
return 0;
【讨论】:
【参考方案2】:与其从实现开始并向我们展示 - 您应该从抽象算法(和数据结构)开始,并尽最大努力确保那是合理的。另外,我建议不要过多关注单个指令和循环变量的序列,而是关注它的全局。
所以,这是一个相对幼稚的算法:
为(潜在)路径中的每个节点运行一个阶段:因此,在您的情况下,最多 26 个阶段。 在每个阶段,您都持有路径可以到达的矩阵位置集;然后你推导出这些路径可以通过另一个步骤到达的位置集。换句话说,您正在推进一条多条道路的“前沿”,一次一步。 相位动作可以通过尝试从每个前面的位置向前移动来实现(例如,检查前面的哪个 'f' 有一个相邻的 'g');或者通过尝试从具有适当相位值的每个矩阵元素向后移动(例如,搜索矩阵中的哪些 g 与前一个前面的 f 相邻。)这与您的方法不同,因为在各个路径上没有递归。这种递归可能会很快爆发。虽然您的路径确实不能超过 26 个字符,但原则是有问题的。假设您有一个如下所示的对角矩阵:
abcde ...
bcde ...
cde ...
de ...
e ...
.
.
.
左右移动的任意组合都是有效路径;所以从 a 开始有 2^k 条长度为 k 的路径。你想调用你的longestPath()
2^26 次吗?如果你不必... :-(
【讨论】:
以上是关于找出矩阵中最长路径的长度,其中包含连续字符及其路径的主要内容,如果未能解决你的问题,请参考以下文章