LeeCode 2060 DP

题意

传送门 LeeCode 2060 同源字符串检测

题解

考虑如何进行匹配。由于字符串编码的性质,匹配串间会出现长度差,若串 s s s 比串 t t t 长的部分存在字母,则会难以处理。

考虑从当前已处理部分较短的字符串进行处理,那么字符串长度差不会超过 1 0 3 10^3 103;若长度差为零,则优先处理后续部分为数字型字符的字符串,若不存在这样的字符串,那么直接匹配字符即可。此时保证串 s s s 比串 t t t 长的部分都是可以任意匹配的字符。

d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k] 代表串 s s s [ 0 , i ) [0,i) [0,i) 与串 t t t [ 0 , j ) [0,j) [0,j) 匹配且长度差为 k k k 的情况是否存在。对数字部分枚举分界点处理即可。设 s , t s,t s,t 长度分别为 N , M N,M N,M,连续的数字型字符最长为 D D D,总时间复杂度 O ( M N D × 1 0 D ) O(MND\times 10^D) O(MND×10D)

class Solution
{
    
    
    static const int MAX_N = 45, MAX_D = 1005;

public:
    int N, M;
    bool dp[MAX_N][MAX_N][MAX_D * 2];
    bool possiblyEquals(string s1, string s2)
    {
    
    
        N = s1.size(), M = s2.size();
        for (int i = 0; i <= N; ++i)
            for (int j = 0; j <= M; ++j)
                memset(dp[i][j], 0, sizeof(dp[i][j]));
        dp[0][0][MAX_D] = 1;
        for (int i = 0; i <= N; ++i)
            for (int j = 0; j <= M; ++j)
                for (int k = -1000; k <= 1000; ++k)
                    if (dp[i][j][k + MAX_D])
                    {
    
    
                        if (k == 0 && isalpha(s1[i]) && isalpha(s2[j]) && s1[i] == s2[j])
                            dp[i + 1][j + 1][k + MAX_D] = 1;
                        if (k > 0 && isalpha(s2[j]))
                            dp[i][j + 1][k - 1 + MAX_D] = 1;
                        if (k < 0 && isalpha(s1[i]))
                            dp[i + 1][j][k + 1 + MAX_D] = 1;
                        if (k >= 0 && isdigit(s2[j]))
                            for (int l = j, x = 0; l < M; ++l)
                            {
    
    
                                if (!isdigit(s2[l]))
                                    break;
                                x = (x << 1) + (x << 3) + s2[l] - '0';
                                dp[i][l + 1][k - x + MAX_D] = 1;
                            }
                        if (k <= 0 && isdigit(s1[i]))
                            for (int l = i, x = 0; l < N; ++l)
                            {
    
    
                                if (!isdigit(s1[l]))
                                    break;
                                x = (x << 1) + (x << 3) + s1[l] - '0';
                                dp[l + 1][j][k + x + MAX_D] = 1;
                            }
                    }
        return dp[N][M][MAX_D];
    }
};

Guess you like

Origin blog.csdn.net/neweryyy/article/details/121107498
DP