[LeetCode] 479. 最大回文数乘积

229 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第18天,点击查看活动详情

479. 最大回文数乘积

给定一个整数 n ,返回 可表示为两个 n 位整数乘积的 最大回文整数 。因为答案可能非常大,所以返回它对 1337 取余

示例 1:

输入:n = 2
输出:987
解释:99 x 91 = 9009, 9009 % 1337 = 987

示例 2:

输入: n = 1
输出: 9

提示:

  • 1 <= n <= 8

解题思路

可以从大到小枚举回文数,枚举回文数的前半部分,其后半部分也就确定了,因此我们只需要枚举左半部分,同时由于两个 n 位整数的乘积至多是个 2n位数,我们可以从 10^n-1 始枚举回文数的前半部分。

func largestPalindrome(n int) int {
    if n == 1 {
        return 9
    }
    High := int(math.Pow10(n)) - 1
    for Low := High; ; Low-- {
        cur := Low
        for x := Low; x > 0; x /= 10 {
            cur = cur * 10 + x % 10
        }
        for x := High; x * x >= cur; x-- {
            if cur % x == 0 {
                return cur % 1337
            }
        }
    }
    return 0
}

647. 回文子串

难度:中等

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

回文字符串 是正着读和倒过来读一样的字符串。

子字符串 是字符串中的由连续字符组成的一个序列。

具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"

示例 2:

输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

提示:

  • 1 <= s.length <= 1000
  • s 由小写英文字母组成

解题思路

  • 状态:dp[i][j] 表示字符串s[i,j]区间的子串是否是一个回文串。
  • 状态转移方程:当 s[i] == s[j] && (j - i < 2 || dp[i + 1][j - 1]) 时,dp[i][j]=true,否则为false
class Solution {
public:
    int countSubstrings(string s) {
        int ans = 0, n = s.size();
        vector<vector<bool>> dp(n,vector<bool>(n,false));
        for(int i = n - 1; i >= 0; i--){
            for(int j = i;j < n; j++){
                if(s[i] == s[j] and (j - i <= 2 or dp[i + 1][j - 1])){
                    ans++;
                    dp[i][j] = true;
                }
            }
        }
        return ans;
    }
};