最长回文子串检测异常:输入hellosannasmith返回none问题排查
最长回文子串动态规划算法问题排查
我正在实现一个寻找给定字符串中最长回文子串的算法,采用动态规划思路,代码如下:
public static string Find_LongestPalindrome(string s) { var charsArray = s.ToCharArray(); var boolArr = new bool[charsArray.Length, charsArray.Length]; int longestStart = 0; int maxLength = 1; // 默认单个字符都是回文 for (int i = 0; i < charsArray.Length; i++) { boolArr[i, i] = true; } // 检查长度为2的回文 for (int i = 0; i < charsArray.Length - 1; i++) { if (charsArray[i] == charsArray[i + 1]) { boolArr[i, i + 1] = true; longestStart = i; maxLength = 2; } } // 检查长度大于2的回文 for (int length = 2; length <= charsArray.Length; length++) { for (int i = 0; i < charsArray.Length - length + 1; i++) { int j = i + length - 1; if (charsArray[i] == charsArray[j] && boolArr[i + 1, j - 1]) { boolArr[i, j] = true; if (maxLength < (j - i)) { maxLength = j - i; longestStart = i; } } } } // 返回结果 if (s.Length == longestStart + (maxLength + 1)) { return s.Substring(longestStart, maxLength + 1); } else { return s = "none"; } }
该算法要求找到长度至少为2的最长回文子串,目前能正确处理输入1(hellosmithsannas,返回sannas)和输入3(abcdefgg,返回none),但处理输入2(hellosannasmith)时,本该返回sannas却返回了none,请问哪里存在问题?
问题分析与修正
1. 核心错误:返回逻辑的判断条件完全错误
最后一段的判断条件s.Length == longestStart + (maxLength + 1)完全不合理,它错误地认定只有当找到的回文子串刚好占据从longestStart到字符串末尾的位置时,才返回该子串,否则直接返回none。
对于输入hellosannasmith,sannas的起始位置并非字符串末尾,这个条件不满足,所以错误返回了none。
2. 次要问题:maxLength的含义混淆
代码中maxLength的存储逻辑不直观:
- 找到长度为2的回文时,
maxLength被设为2(实际长度); - 找到更长的回文时,
maxLength被设为j-i(即实际长度减1),后续需要通过maxLength+1获取实际长度。
这种混合存储方式容易引发逻辑错误,建议统一用maxLength存储回文的实际长度。
修正后的代码
public static string Find_LongestPalindrome(string s) { if (string.IsNullOrEmpty(s) || s.Length < 2) return "none"; var charsArray = s.ToCharArray(); var boolArr = new bool[charsArray.Length, charsArray.Length]; int longestStart = 0; int maxLength = 1; // 默认单个字符都是回文 for (int i = 0; i < charsArray.Length; i++) { boolArr[i, i] = true; } // 检查长度为2的回文 for (int i = 0; i < charsArray.Length - 1; i++) { if (charsArray[i] == charsArray[i + 1]) { boolArr[i, i + 1] = true; longestStart = i; maxLength = 2; } } // 检查长度大于2的回文,length从3开始(避免重复处理长度为2的情况) for (int length = 3; length <= charsArray.Length; length++) { for (int i = 0; i < charsArray.Length - length + 1; i++) { int j = i + length - 1; if (charsArray[i] == charsArray[j] && boolArr[i + 1, j - 1]) { boolArr[i, j] = true; // 直接比较实际长度length if (maxLength < length) { maxLength = length; longestStart = i; } } } } // 判断是否找到长度>=2的回文 return maxLength >= 2 ? s.Substring(longestStart, maxLength) : "none"; }
关键修正点
- 替换返回逻辑:只要
maxLength >=2(说明找到符合要求的回文),就返回对应的子串,否则返回none; - 统一
maxLength存储实际回文长度,循环从length=3开始(避免重复处理长度为2的情况); - 增加空字符串或长度不足2的边界判断,逻辑更健壮。
内容的提问来源于stack exchange,提问作者AT-2017
相关产品推荐
相关产品推荐

