最大回文子串和分割回文串

leetcode 5. 最长回文子串

  • 暴力,时间复杂度O(N^3)
func longestPalindrome(s string) string {
    n := len(s)
    maxLength,logest := 0,""
    for i :=0;i<n;i++{
        for j:=i+1;j<=n;j++{
            if isPalindrome(s[i:j]) && j-i > maxLength{
                maxLength = j-i
                logest = s[i:j]
            }
        }
    }
    return logest
}


func isPalindrome(s string)bool {
    n := len(s)
    for i := 0;i<n/2;i++{
        if s[i] != s[n-1-i]{
            return false
        }
    }
    return true
}
  • 动态规划,时间和空间复杂度O(N^2)
func longestPalindrome(s string) string {
    n := len(s)
    if n == 0 {
        return s
    }
    // dp [i][j]表示 s[i:j+1]是否是回文串
    // dp [i][j] = s[i] == s[j] && dp[i+1][j-1]
    // 所以计算 dp[i][j]时一定要提前计算dp[i+1][j-1],所以i应当是从大到小,j是从小到大,且j>i
    dp := make([][]bool,n)
    for i:=0;i<n;i++{
        dp[i] = make([]bool,n)
        dp[i][i] = true
    }
    maxLen,start := 1,0
    for i := n-1;i>=0;i--{
        for j:=i+1;j<n;j++{
            dp[i][j] = (s[i]==s[j])&& (j-i<3 || dp[i+1][j-1])
            if dp[i][j]{
                if j-i+1 > maxLen{
                    maxLen = j-i+1
                    start = i
                }
            }
        }
    }
    return s[start:start+maxLen]
}

func isPalindrome(s string)bool {
    n := len(s)
    for i := 0;i<n/2;i++{
        if s[i] != s[n-1-i]{
            return false
        }
    }
    return true
}
  • 中心扩展,时间复杂度O(N^2),空间复杂度O(1)
func longestPalindrome(s string) string {
    n := len(s)
    if n == 0 {
        return ""
    }
    var start,end int
    for i := 0;i< n;i++{
        len1,len2 := expand(s,i,i),expand(s,i,i+1)
        len := max(len1,len2)
        if len> end - start {
            start = i-(len-1)/2
            end = i +len/2
        }
    }
    return s[start:end+1]
}

func max(x,y int) int {
    if x > y {
        return x
    }
    return y
}

func expand(s string,l,r int) int{
    n := len(s)
    for l >=0 && r < n && s[l] == s[r]{
        l,r = l-1,r+1
    }
    return r - l -1
}

leetcode 131. 分割回文串

  • 回溯,加动态规划预处理
func partition(s string) [][]string {
	n := len(s)
	if n == 0 {
		return nil
	}

	// dp[i][j]表示s[i:j+1]是否回文
	// dp[i][j] = s[i] == s[j] && dp[i+1][j-1]
	dp := make([][]bool, n)
	for i := 0; i < n; i++ {
		dp[i] = make([]bool, n)
		dp[i][i] = true
	}
	// 获得所有回文子串
	for i := n - 1; i >= 0; i-- {
		for j := i + 1; j < n; j++ {
			dp[i][j] = s[i] == s[j] && (j-i < 3 || dp[i+1][j-1])
		}
	}
	return backTrack(s, 0, n, dp, []string{}, [][]string{})
}

func backTrack(s string, start, n int, dp [][]bool, path []string, ret [][]string) [][]string {
	// 字符串分割完毕,将结果加入到结果集
	if start == n {
		tmp := make([]string, len(path))
		copy(tmp, path)
		return append(ret, tmp)
	}
	for i := start; i < n; i++ {
		// 当前s[start:i+1]是回文,接下来判断其后面是不是回文(前面已经判断过了)
		if dp[start][i] {
			ret = backTrack(s, i+1, n, dp, append(path, s[start:i+1]), ret)
		}
	}
	return ret
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值