对于长度为n的一个字符串A(仅包含数字,大小写英文字母),请设计一个高效算法,计算其中最长回文子串的长度。
数据范围:
要求:空间复杂度 ,时间复杂度
进阶: 空间复杂度 ,时间复杂度
/** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string 字符串 * @return int 整型 */ function getLongestPalindrome(s) { //计算最长回文子串的长度,dp数组的含义 dp[i][j] 代表字符串 [i,j]的是不是回文字符串 const dp = new Array(s.length).fill(0).map(_ => new Array(s.length).fill(false)) let count = 0 for (let i = s.length - 1; i >= 0; i--) { for (let j = i; j < s.length; j++) { if (s.charAt(i) === s.charAt(j)) { if (j - i <= 1) { if (j - i + 1 > count) { count = j - i + 1 } dp[i][j] = true } else if (j - i > 1) { if (dp[i + 1][j - 1]) { if (j - i + 1 > count) { count = j - i + 1 } } dp[i][j] = dp[i + 1][j - 1] } } } } console.table(dp) return count } console.log(getLongestPalindrome("ccbcabaabba"));
Javascript 中心扩散
function getLongestPalindrome( A ) { // write code here let max = 0; const palindrome = (l, r) =>{ // 中心扩散,找最长回文长度 while(l >= 0 && r <= A.length) { if(A[l] !== A[r]) break; l--,r++; } return r - l - 1; // 注意这个值的计算,因为最后一次扩散总是出界,或者不是回文,所以长度已经扩了需要减去 } for(let i = 0; i < A.length; i++) { // 简单遍历就好了 max = Math.max(palindrome(i, i), max); // 从一个点扩散 max = Math.max(palindrome(i, i + 1), max); // 从两个点扩散 } return max; }
// 一、双中心检测法 function getLongestPalindrome0(A) { // write code here const n = A.length if (n === 1) { return A[0] } let maxLen = 0 let subList = [] for (let i = 0; i < n; i++) { let l, r for (l = i, r = i; A[l] === A[r] && l >= 0 && r < n; l--, r++) {} if (maxLen < r - l - 1) { maxLen = r - l - 1 subList = [A.slice(l + 1, r)] } else if (maxLen === r - l - 1) { subList.push(A.slice(l + 1, r)) } for (l = i, r = i + 1; A[l] === A[r] && l >= 0 && r < n; l--, r++) {} if (maxLen < r - l - 1) { maxLen = r - l - 1 subList = [A.slice(l + 1, r)] } else if (maxLen === r - l - 1) { subList.push(A.slice(l + 1, r)) } } return { maxLen, subList } } // 二、动态规划 function getLongestPalindrome(A) { const n = A.length const dp = [] let maxLen = 0 // let subList = [] for (let i = 0; i < n; i++) { dp[i] = [] dp[i][i] = 1 // subList.push(A[i]) maxLen = 1 } for (let i = n - 1; i >= 0; i--) { for (let j = i + 1; j < n; j++) { if (A[i] === A[j]) { if (j - i <= 2) { dp[i][j] = j - i + 1 } else { dp[i][j] = dp[i + 1][j - 1] + 2 } if (maxLen < dp[i][j]) { maxLen = dp[i][j] // subList = [A.slice(i, j + 1)] } // else if (maxLen === dp[i][j]) { // subList.push(A.slice(i, j + 1)) // } } } } return maxLen // return { maxLen, subList, dp: JSON.stringify(dp) } }
function getLongestPalindrome(A) { let arr = A.split("") // 找出所有回文子串 let resultArr = [] while (arr.length > 0) { if (IsPalindrome([...arr])) { resultArr.push(arr.length) // Math.max()方法传入多个值 return Math.max(...resultArr) } else { let len = MaxPalindrome([...arr]) if (len > 1) { resultArr.push(len) } arr.shift() } } } // 判断已当前字母开头最大的回文长度 function MaxPalindrome(arr) { while (arr.length > 1) { arr.pop() if (IsPalindrome([...arr])) { return arr.length } } } // 判断当前数组是否为回文数组 function IsPalindrome(arr) { if (arr[0] === arr[arr.length - 1]) { let spliceArr = arr.splice(1, arr.length - 2) if (spliceArr.length >= 2) { return IsPalindrome(spliceArr) } else { return true } } else { return false } }找啊找,从头找到尾
function getLongestPalindrome( A ) { if (!A) { return 0; } const strLen = A.length; if (strLen < 2) { return 1; } if (strLen === 2) { return A.charAt(0) === A.charAt(1) ? 2 : 1; } const maxSize = A % 2 === 0 ? strLen - 1 : strLen; let maxSubLen = 1; const checkValid = (str) => { const len = str.length; const checkCount = len % 2 === 0 ? len / 2 : (len - 1) / 2; let result = true; for (let i = 0; i < checkCount; i++) { if (str.charAt(i) !== str.charAt(len - (i + 1))) { result = false; break; } } return result; } for (let j = 3; j <= maxSize; j += 1) { for (let i = 0; i + j <= strLen; i++) { const subStr = A.slice(i, i + j); const isValid = checkValid(subStr); if (isValid) { maxSubLen = Math.max(j, maxSubLen); } } } return maxSubLen; }
/** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param A string字符串 * @return int整型 */ function getLongestPalindrome( A ) { // write code here //需要改进成dp写法 let max=1; for(let i=0;i<A.length;i++){ for(let j = 1; j <=A.length; j++){ let cur = A.substr(i,j) if(isP(cur)){ max = Math.max(max,cur.length); } } } return max; } function isP(str){ for(let i=0;i<str.length;i++){ if(str[i]!=str[str.length-i-1]){ return false } } return true } module.exports = { getLongestPalindrome : getLongestPalindrome };
function getLongestPalindrome( A ) { if (!A) { return "" }; let res = 1; for (let i=0; i < A.length; ++i) { const r = symmetry(i, A); if (r > res) { res = r; } } return res; } function symmetry(pos, str) { let i = pos, j = pos - 1; while (i <= str.length && str[i] === str[pos]) { ++i; } while (i <= str.length && j >= 0 && str[i] === str[j]) { ++i;--j; } return i - j - 1; }
export function getLongestPalindrome(A: string, n: number): number { // write code here let res = 1; for (let i = 0.5; i < A.length; i += 0.5) { let [left, right] = Number.isInteger(i) ? [i - 1, i + 1] : [i - 0.5, i + 0.5]; for (; left >= 0 && right <= A.length - 1; left--, right++ ) { if (A.charAt(left) === A.charAt(right)) res = Math.max(right - left + 1, res); else break; } } return res; }
function getLongestPalindrome(A, n) { //中心扩散法 function func(A,left,right){ while(left>=0 && right<n && A[left]==A[right]){ left-- right++ } return right-left+1-2 //为什么还要减2 因为上面while循环终止了,此时A[left] != A[right] //所以此时的回文子串的左右边界其实是 l-1, r+1 } let res=0 for(let i=0;i<A.length;i++){ // 区分奇偶字串 res=Math.max(res,func(A,i,i),func(A,i,i+1)) } return res }
export function getLongestPalindrome(A: string, n: number): number { // write code here if(!n) return 0 let res = 1 const dp = [] for(let i = n -1;i>=0;i--){ dp[i] = [] for(let j = i;j<n;j++){ if(j - i == 0) dp[i][j] = true else if(A[i] == A[j]&&j-i == 1) dp[i][j] = true else if(A[i] == A[j] && dp[i+1][j-1]) dp[i][j] = true if( dp[i][j]&& j - i + 1 >res) res = j - i + 1 } } return res }