求解LeetCode最长回文子串问题时遇std::out_of_range错误排查
LeetCode第5题《最长回文子串》Runtime Error问题排查
问题场景
我在解决LeetCode第5题《最长回文子串》(给定字符串s,返回s中最长的回文子串)时,写出了如下C++代码,但运行时触发std::out_of_range错误,错误提示:
basic_string::substr: __pos(值为18446744073709551615)>this->size()(值为5)
0/141个测试用例通过,请问问题出在哪里?
原代码
class Solution { public: string longestPalindrome(string s) { string res=""; //stores the result of longest palindrome substring int n=s.size(); for(int i=1;i<s.length();i++) { int low=i; int high=i; while(s.at(low)==s.at(high)) { low--; high++; if(low==-1 || high==s.length() ) break; } string str=s.substr(low,high); if(str.size()>res.size()) res=str; low=i-1; high=i; while(s.at(low)==s.at(high)) { low--; high++; if(low==-1 || high==s.length() ) break; } str=s.substr(low,high); if(str.length()>res.length()) res=str; } return res; } };
错误原因分析
负数下标传递给
substr导致溢出
循环中当low减到-1时触发break,但此时low是负数。substr的第一个参数是size_t类型(无符号整数),负数转换为无符号整数会变成极大值(即错误提示中的18446744073709551615),远超过字符串长度,直接触发out_of_range异常。substr参数使用错误string::substr的签名是substr(size_t pos = 0, size_t len = npos),第二个参数是子串长度,不是结束索引。你当前传递的high是结束位置的下一个索引,这会导致截取的子串长度远超预期,甚至越界。循环起始位置错误
循环从i=1开始,漏掉了i=0的情况。当字符串长度为1时,会直接返回空字符串,不符合题目要求;同时也会错过以第一个字符为中心的奇数长度回文。越界访问风险
while循环中先执行s.at(low)==s.at(high),再判断边界。当low已经是-1或high等于字符串长度时,s.at()会直接触发越界异常,因为at()会检查下标合法性。
修复后的代码
class Solution { public: string longestPalindrome(string s) { if (s.empty()) return ""; string res = s.substr(0, 1); // 初始化结果为第一个字符,处理长度为1的情况 int n = s.size(); for (int i = 0; i < n; ++i) { // 处理奇数长度回文(中心为单个字符) int low = i, high = i; while (low >= 0 && high < n && s[low] == s[high]) { low--; high++; } // 有效回文区间是 [low+1, high-1],长度为 high - low -1 string oddStr = s.substr(low + 1, high - low - 1); if (oddStr.size() > res.size()) { res = oddStr; } // 处理偶数长度回文(中心为两个相邻字符) low = i, high = i + 1; while (low >= 0 && high < n && s[low] == s[high]) { low--; high++; } string evenStr = s.substr(low + 1, high - low - 1); if (evenStr.size() > res.size()) { res = evenStr; } } return res; } };
修复说明
- 先判断字符串为空的情况,直接返回空。
- 初始化
res为第一个字符,处理字符串长度为1的场景。 - 循环从
i=0开始,覆盖所有可能的回文中心。 while循环先判断边界(low >=0 && high <n),再比较字符,避免越界访问。- 截取子串时,起始位置为
low+1(因为最后一次low--导致越界或不相等),长度为high - low -1,确保截取的是有效的回文子串。
内容的提问来源于stack exchange,提问作者shubham
相关产品推荐
相关产品推荐

