LintCode - 문서 문자열 분할 II

1586 단어 면접 시험lintcode
문자열 s를 지정하고, s를 일부 하위 문자열로 나누어, 모든 하위 문자열이 회문으로 되도록 합니다.
s가 요구에 부합되는 최소 분할 횟수를 되돌려줍니다.
당신은 실제 면접에서 이 문제를 만난 적이 있습니까? 
Yes
예제
예를 들어 문자열 s = "aab"을 주고
문자열 s를 [aa','b'] 두 개의 문자열로 분할할 수 있기 때문에 1을 되돌려줍니다
라벨
Expand  
관련 문제
Expand 
분석: 처음에 n의 dp를 세 번 썼는데 그 결과 시간이 초과되었다. 그 차이는 dp[i][j]=min(dp[i][k]+dp[k+1][j]+1)의 사상이다. 그러면 반드시 그것을 n제곱의 dp로 최적화시켜야 한다. 그래서 워드브레이크 문제를 연상하게 된다. 만약에 s[i][j]가 회문열이면 dp[j]=dp[i-1]+1으로 2차원 dp에서 1차원 dp로 간소화하여 복잡도를 낮출 수 있다.
코드:
class Solution {
public:
    /**
     * @param s a string
     * @return an integer
     */
    int minCut(string s) {
        // write your code here
        int n = s.length();
        vector<vector<bool> > dp1(n,vector<bool>(n,false));
        for(int len = 1;len<=n;len++)
        {
            for(int i=0;i+len-1<n;i++)
            {
                int j = i+len-1;
                if(len==1)
                {
                    dp1[i][j]=true;
                }
                else
                {
                    if(s[i]==s[j]&&(i==j-1||dp1[i+1][j-1]))
                        dp1[i][j] = true;
                }
            }
        }
        vector<int > dp2(n,INT_MAX);
        for(int i=0;i<n;i++)
        {
            if(dp1[0][i])
                dp2[i] = 0;
            for(int j=0;j<i;j++)
            {
                if(dp1[j+1][i])
                    dp2[i] = min(dp2[i],dp2[j]+1);
            }
        }
        return dp2[n-1];
        
    }
    
};

좋은 웹페이지 즐겨찾기