在实现的时候,我们需要处理一个问题,即如何有序地枚举所有可能的回文中心,我们需要考虑回文长度是奇数和回文长度是偶数的两种情况。如果回文长度是奇数,那么回文中心是一个字符;如果回文长度是偶数,那么中心是两个字符。当然你可以做两次循环来分别枚举奇数长度和偶数长度的回文,但是我们也可以用一个循环搞定。我们不妨写一组出来观察观察,假设 n = 4,我们可以把可能的回文中心列出来:
classSolution { public: intcountSubstrings(string s){ int n = s.size(), ans = 0; for (int i = 0; i < 2 * n - 1; ++i) { int l = i / 2, r = i / 2 + i % 2; while (l >= 0 && r < n && s[l] == s[r]) { --l; ++r; ++ans; } } return ans; } };
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { publicintcountSubstrings(String s) { intn= s.length(), ans = 0; for (inti=0; i < 2 * n - 1; ++i) { intl= i / 2, r = i / 2 + i % 2; while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) { --l; ++r; ++ans; } } return ans; } }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13
var countSubstrings = function(s) { const n = s.length; let ans = 0; for (let i = 0; i < 2 * n - 1; ++i) { let l = i / 2, r = i / 2 + i % 2; while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) { --l; ++r; ++ans; } } return ans; };
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12
intcountSubstrings(char* s) { int n = strlen(s), ans = 0; for (int i = 0; i < 2 * n - 1; ++i) { int l = i / 2, r = i / 2 + i % 2; while (l >= 0 && r < n && s[l] == s[r]) { --l; ++r; ++ans; } } return ans; }
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13
funccountSubstrings(s string)int { n := len(s) ans := 0 for i := 0; i < 2 * n - 1; i++ { l, r := i / 2, i / 2 + i % 2 for l >= 0 && r < n && s[l] == s[r] { l-- r++ ans++ } } return ans }
classSolution { public: intcountSubstrings(string s){ int n = s.size(); string t = "#"; for (constchar &c: s) { t += c; t += '#'; } n = t.size(); t += '!';
auto f = vector <int> (n); int iMax = 0, rMax = 0, ans = 0; for (int i = 1; i < n; ++i) { // 初始化 f[i] f[i] = (i <= rMax) ? min(rMax - i + 1, f[2 * iMax - i]) : 1; // 中心拓展 while (t[i + f[i]] == t[i - f[i]]) ++f[i]; // 动态维护 iMax 和 rMax if (i + f[i] - 1 > rMax) { iMax = i; rMax = i + f[i] - 1; } // 统计答案, 当前贡献为 (f[i] - 1) / 2 上取整 ans += (f[i] / 2); }
var countSubstrings = function(s) { let n = s.length; let t = ['', '#']; for (let i = 0; i < n; ++i) { t.push(s.charAt(i)); t.push('#'); } n = t.length; t.push('!'); t = t.join('');
const f = newArray(n); let iMax = 0, rMax = 0, ans = 0; for (let i = 1; i < n; ++i) { // 初始化 f[i] f[i] = i <= rMax ? Math.min(rMax - i + 1, f[2 * iMax - i]) : 1; // 中心拓展 while (t.charAt(i + f[i]) == t.charAt(i - f[i])) { ++f[i]; } // 动态维护 iMax 和 rMax if (i + f[i] - 1 > rMax) { iMax = i; rMax = i + f[i] - 1; } // 统计答案, 当前贡献为 (f[i] - 1) / 2 上取整 ans += Math.floor(f[i] / 2); }