横向扫描教你搞定“最长公共前缀”问题

一、前言

昨天做了leetcode上简单等级的14.最长公共前缀问题,今天来做个小结,主要是针对横向扫描算法进行展开分析。

二、最长公共前缀

1.题意

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”

2.示例

示例 1
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”

示例 2
输入:strs = [“dog”,“racecar”,“car”]
输出:""
解释:输入不存在公共前缀。

3.题解

横向扫描

思路分析

横向扫描图解:
横向扫描的大致思路简单来说,首先确定字符串数组内字符的最短长度minlen,最长公共前缀的长度不大于该最短长度,接着只需依次遍历字符串数组中的每个字符串的前minlen位,两两之间查找公共字符串,更新最长公共前缀,再用最新的最长公共前缀继续依次往后遍历扫描匹配,当遍历完所有的字符串之后,就能得到最长公共前缀。当然,如果在没有遍历完所有字符串之前,所更新的最长字符串已经是空串了,则无需再往后继续遍历,直接返回空串即可。
请添加图片描述

代码解析
C语言代码解析及详细注释说明

代码是自思自写的哈,救命!!!折腾了我好久,终于成功执行啦!现在回头看当时整整提交了30次,一直到第31次才成功。报错的原因主要有三种:
①代码设计不够周全,没有想到strsSize=1的情况,以致于如果运行实例中字符串数组长度只有1的话,会输出空,而不是输出第一个字符串。根据报错信息将代码进行调整,成功解决

else if(strsSize == 1)
return strs[0];

②在横向扫描两层遍历的过程中没有考虑到当字符串数组中的两个字符串中的第一个字符在比较时就发现不相等时,应该立即返回“”,而只是在判断某个字符不等时就返回result,没想到这样可能会导致下面这种情况的出现:

示例:[“fa”,“fa”,""]
输出:[“fa”]

最后在第二层for循环体内的if(strs[i][j] != strs[0][j])中增加判断条件,即可解决这个问题:

for(j = 0; j < minlen; j++)
{
if(strs[i][j] != strs[0][j])
{ if(j == 0)
return “”;
break;
}

③执行不停出错,报错信息为==【ERROR:AddressSanitizer:heap-buffer-overflow on address 0x602000000272 at pc ……】,也有到网上去查过报出此类出错信息可能是什么错误导致的,发现有可能是由于数组下标溢出==导致的,仔细检查横向扫描部分的代码:在我的代码设计中有一块是这样设计的:当两个字符串进行匹配,除第一个字符串就匹配失败的情况以外,一旦中途出现字符匹配失败,就更新最短字符串长度为匹配失败的字符索引值j+1。后面发现应该更新为j而不是j+1,怀疑数组溢出就是指的这,结果更改之后,仍然报错且报错信息一致。
就在我想放弃的时候,想着最后再修改一次,就这样成功啦!主要是将原先条件判断strs[i][j] != strs[0][j]内j != 0的return删除,改为了break。之所以这样改是因为如果不考虑字符串还没有遍历完成就返回result,这样势必会出错。最后更改过后,代码执行成功

for(int i = 1; i < strsSize; i++)
{
for(j = 0; j < minlen; j++)
{
if(strs[i][j] != strs[0][j])
{ if(j == 0)
return “”;
break;
}
result[j] = strs[0][j];
result[j+1] = ‘\0’;
}
minlen = j;
}
return result;

请添加图片描述

//最长公共前缀功能函数
char * longestCommonPrefix(char ** strs, int strsSize){
   
    if(!strsSize)//字符串数组长度为0,返回""空串
        return "";
    else if(strsSize == 1)//字符串数组长度为1,返回第一个字符串
        return strs[0]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值