【科学刷题】回文题

这篇博客主要探讨了关于回文的编程题目,包括整数反转、最长回文子串、回文数和字符串转换成整数的问题。重点介绍了中心扩散法、动态规划和“马拉车”算法,并讨论了如何避免将整数转化为字符串来解决回文数问题。同时,提到了Python中字符串转换整数的实现方式。
摘要由CSDN通过智能技术生成

7. 整数反转

7. 整数反转

class Solution {
public:
    int reverse(int x) {
        int ret=0;
        while(x!=0){
            int pop=x%10;
            x/=10;
            if(ret>INT_MAX/10 ||(ret==INT_MAX && pop>7)) return 0;
            if(ret<INT_MIN/10 ||(ret==INT_MIN && pop<-7)) return 0;
            ret=ret*10+pop;
        }
        return ret;
    }
};

5. 最长回文子串

  • 中心扩散法
  • DP(待办)
class Solution:
    def longestPalindrome(self, s: str) -> str:

        def func(s, i, j):
            while 0 <= i and j < len(s) and s[i] == s[j]:
                i -= 1
                j += 1
            i += 1
            j -= 1
            return i, j

        sa, sb = 0, 0
        for i in range(len(s)):
            a, b = func(s, i, i)
            if b - a > sb - sa:
                sa, sb = a, b
            if i < len(s) - 1:
                a, b = func(s, i, i + 1)
                if b - a > sb - sa:
                    sa, sb = a, b
        return s[sa:(sb + 1)]

动态规划——你超容易理解的船新版本

在这里插入图片描述

214. 最短回文串

哈希,KMP,马拉车。。我先选择放弃

在这里插入图片描述

在这里插入图片描述
奇数key不超过1

return sum(1 for val, cnt in collections.Counter(s).items() if cnt%2)<=1

336. 回文对

字典树+马拉车,放弃

516. 最长回文子序列

子序列问题通用思路|最长回文子序列

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        n = len(s)
        dp = [[0] * n for _ in range(n)]
        for i in range(n):
            dp[i][i] = 1
        for i in range(n - 1):
            dp[i][i + 1] = 2 if s[i] == s[i + 1] else 1
        for k in range(2,n):
            for i in range(n - k):
                j = i + k
                if s[i] == s[j]:
                    dp[i][j] = dp[i + 1][j - 1] + 2
                else:
                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
        return dp[0][n - 1]

647. 回文子串

“马拉车”算法:基于中心扩散+剪枝原理

有空看,头痛

应该就是特化版的

但是马拉车很快,ON

在这里插入图片描述

class Solution:
    #中心扩散+马拉车优化 时间复杂度o(n),空间复杂度 o(n)
    def countSubstrings(self, s: str) -> int:
        s = "#" + "#".join(s) + "#"
        right = -1
        maxlen = [0]*len(s)
        res = 0
        for i in range(len(s)):
            if i<=right:
                im = 2*j-i
                minlen = min(maxlen[im],right-i)
                tmp = self.expand(s,i-minlen,i+minlen)
            else:
                tmp = self.expand(s,i,i)
            maxlen[i] = tmp
            if i+tmp>right:
                right = i+tmp
                j = i
            if i%2==1:
                res += maxlen[i]//2 + 1
            else:
                res += (maxlen[i]+1)//2
        return res


    def expand(self,s,l,r):
        while 0<=l and r<len(s) and s[l] == s[r]:
            l -= 1
            r += 1
        return (r-l)//2 - 1
class Solution:
    def countSubstrings(self, s: str) -> int:
        res = 0
        n = len(s)
        dp = [[0] * n for _ in range(n)]
        for i in range(n):
            for j in range(i + 1):
                if s[i] == s[j] and (i - j < 2 or dp[j + 1][i - 1]):
                    dp[j][i] = 1
                    res += 1
        return res
class Solution:
    def countSubstrings(self, s: str) -> int:
        L = len(s)
        cnt = 0
        # 以某一个元素为中心的奇数长度的回文串的情况
        for center in range(L):
            left = right = center
            while left >= 0 and right < L and s[left] == s[right]:
                cnt += 1
                left -= 1
                right += 1
        # 以某对元素为中心的偶数长度的回文串的情况
        for left in range(L - 1):
            right = left + 1
            while left >= 0 and right < L and s[left] == s[right]:
                cnt += 1
                left -= 1
                right += 1

        return cnt

9. 回文数

9. 回文数

class Solution:
    def isPalindrome(self, x: int) -> bool:
        return False if x<0 else str(x)==str(x)[::-1]

你能不将整数转为字符串来解决这个问题吗?

class Solution:
    def isPalindrome(self, x: int) -> bool:
        # 排除 10 和 负数 的特殊情况
        if x < 0 or (x % 10 == 0 and x != 0):
            return False
        rx = 0
        while x > rx:
            rx = rx * 10 + x % 10
            x //= 10
        return rx == x or rx // 10 == x

8. 字符串转换整数 (atoi)

8. 字符串转换整数 (atoi)

  • DFA
  • if-else
    • long
    • int, × 10 \times10 ×10前判断
  • Python, 正则表达式

写得头痛。。

int my_atoi(string &s) {
    int num = 0;
    int i = 0;
    int len = s.size();
    int flag = 1;
    while (s[i] == ' ') {
        i++;
    }
    if (s[i] == '+') {
        i++;
    } else if (s[i] == '-') {
        flag = -1;
        i++;
    }
    while (i < len) {
        if (s[i] < '0' || s[i] > '9') break;
        int cur = (int) (s[i] - '0');
        if (num > INT_MAX / 10) { return flag == 1 ? INT_MAX : INT_MIN; }
        if (num == INT_MAX / 10) {
            if (flag == 1 && cur >= 7) return INT_MAX;
            if (flag == -1 && cur >= 8) return INT_MIN;
        }
        num = num * 10 + cur;
        i++;
    }
    return flag * num;
}


class Solution {
public:
    int myAtoi(string s) {
        return my_atoi(s);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值