程式碼隨想錄day46 || 647 迴文子串, 516 最長迴文子序列

周公瑾55發表於2024-08-31

647 迴文字串

image

func countSubstrings(s string) int {
	// 動規五部曲
	// dp[i][j] 表示s[i: j+1] 區間是否是一個迴文
	// if s[i] == s[j] {if i-j <= 1 || dp[i+1][j-1] == true { dp[i][j] == true}}
	// 初始化為false
	// 從下往上,從左往右
	// print

	var count int
	var dp = make([][]bool, len(s))
	for i, _ := range dp {
		dp[i] = make([]bool, len(s))
	}

	for i:=len(s)-1; i>=0; i-- {
		for j:=i; j<len(s); j++ {
			if s[i] == s[j]{
				if j-i<=1 || dp[i+1][j-1] == true {
					dp[i][j] = true
					count++
				}
			}

		}
	}
	//fmt.Println(dp)
	return count
}

516 最長迴文子序列

func longestPalindromeSubseq(s string) int {
	// 647 迴文字串變體,只用統計最長字串即可
	// dp[i][j] 表示s[i: j+1] 最長迴文子串長度
	// s[i] != s[j] {dp[i][j] = max(dp[i+1][j-1], dp[i+1][j], dp[i][j-1])} // 刪除i, 刪除j, 兩個都刪除
	// s[i] == s[j] {dp[i+1][j-1] + 2} // 去除首位之後的最長字串 + 兩個字元長度
	// 初始化為0 , 多初始化一行一列
	// 遞推來自三個方向,左下,左,下,所以遍歷順序從下往上,從左往右
	// print

	var maxlen int
	var dp = make([][]int, len(s) + 1)
	for i, _ := range dp {
		dp[i] = make([]int, len(s) + 1)
	}

	for i:=len(s); i>=0; i-- {
		for j:=i; j<len(s); j++ {
			if s[i] == s[j]{
				if i == j {
					dp[i][j+1] = dp[i+1][j] + 1
				}else {
					dp[i][j+1] = dp[i+1][j] + 2
				}
			} else {
				dp[i][j+1] = max(dp[i+1][j], max(dp[i+1][j+1], dp[i][j]))
			}
			if dp[i][j+1] > maxlen {
				maxlen = dp[i][j+1]
			}
		}
	}
	//fmt.Println(dp)
	return maxlen
}

相關文章