LeetCode第14题最长公共前缀C语言代码运行异常问题求助
问题结论
LeetCode不存在会影响这道题判题结果的偶发运行异常,你耗时两周没定位到问题,根源是自己写的代码有多处bug,和平台没有关系。
你代码里的具体问题
- 公共前缀计算逻辑完全错误:每次遍历新的字符串时,你都会把
matchTillPos重置为0,最终得到的匹配长度只是最后一个字符串和第一个字符串的匹配长度,完全没有和之前所有字符串的匹配结果取最小值。比如输入["flower","flow","flaw"],前两个串公共前缀长度是3("flo"),最后一个串和第一个串公共前缀长度是2("fl"),你的代码会直接返回2作为结果,漏掉前序字符串的匹配约束,结果必然错误。 - 字符串越界访问:内层循环的终止条件是
j < strlen(strs[i]),如果第一个字符串比当前遍历的字符串短,当j超过第一个字符串长度时,访问strs[0][j]会触发越界,属于C语言未定义行为,可能随机出现乱码、崩溃、结果错误的情况。 - 字符串没有终止符:你给静态数组
retStr赋值前缀字符时,没有在末尾添加'\0'作为C字符串的结束标记,函数返回后系统读取字符串时会继续读取数组里残留的旧内存数据,直接导致返回结果带乱码。 - 静态数组残留值干扰:你用
static修饰返回值数组,多次调用函数时数组会保留上一次调用写入的内容,如果本次计算出的前缀长度比上一次短,又没手动加终止符,返回结果会带上上一次调用的旧内容。 - 单元素输入逻辑异常:当
strsSize == 1时,你设置循环从i=0开始,虽然能遍历到第一个字符串本身,但逻辑上完全没必要,还会因为没有主动给返回值加终止符导致结果异常。 - 返回字符串常量风险:没有公共前缀时你直接返回字符串常量
"",部分判题环境如果尝试修改该内存区域会直接触发内存访问错误,导致运行时崩溃。
修正后的可AC代码
char *longestCommonPrefix(char **strs, int strsSize) { static char retStr[201]; // 题目约束单字符串最长200,留1位存终止符 if (strsSize == 0) { retStr[0] = '\0'; return retStr; } // 先统计所有字符串的最短长度,避免越界 int minLen = strlen(strs[0]); for (int i = 1; i < strsSize; i++) { int curLen = strlen(strs[i]); minLen = curLen < minLen ? curLen : minLen; } int matchPos = 0; // 逐位校验所有字符串的同位置字符 for (; matchPos < minLen; matchPos++) { char cur = strs[0][matchPos]; int isSame = 1; for (int i = 1; i < strsSize; i++) { if (strs[i][matchPos] != cur) { isSame = 0; break; } } if (!isSame) break; } // 写入结果并补终止符 for (int i = 0; i < matchPos; i++) { retStr[i] = strs[0][i]; } retStr[matchPos] = '\0'; return retStr; }
内容的提问来源于stack exchange,提问作者Satyam S
相关产品推荐
相关产品推荐

