Leet 97) Interleaving String

7 분 소요

문제

Leetcode - Interleaving String

방법 1

설명

Interleaving String 이라는 유명한 문제이다.

s3 의 문자는 s1s2 에 순서대로 속해야한다. 그래서 기본적인 아이디어는 s1, s2 내의 위치를 가리키는 i, j 를 두어서 s3 의 문자들과 순차적으로 비교해 포인터를 증가시키는 것이다. 예를들어 s1[i] == s3[i+j] 일때 i++ 를 해주는 식.

두 포인터 모두 증가할 수 없다면 조합 불가능이다. 두 포인터 중 하나만 증가하면 간단하겠지만, 두 포인터가 모두 증가할 수 있다면 경우의 수가 나뉘어진다. 하지만 ij 가 증가한 순서는 중요하지 않다. 정확히는 증가한 순서에 따라서 결과값은 달라지지만 그 이후 비교에는 영향을 주지 않는다. 그래서 메모이제이션으로 해결할 수 있다.

아래코드는 이를 BFS 로 해결한 것으로 DFS 를 해도 크게 상관은 없다. 중요한건 중복제거이다.

시간 복잡도

O(\(NM\))

코드

struct P {int i, j;};
class Solution {
public:
    int dp[101][101];
    bool isInterleave(string s1, string s2, string s3) {
        if(s1.size() + s2.size() != s3.size()) return false;
        
        fill(dp[0], dp[101], 0);
        queue<P> q; q.push({0, 0});
        while(!q.empty())
        {
            auto cur = q.front(); q.pop();
            if(cur.i == s1.size() && cur.j == s2.size()) return true;
            if(dp[cur.i][cur.j]) continue;
            dp[cur.i][cur.j] = true;
            if(s1.size() > cur.i && s3[cur.i+cur.j] == s1[cur.i]) q.push({cur.i+1, cur.j});
            if(s2.size() > cur.j && s3[cur.i+cur.j] == s2[cur.j]) q.push({cur.i, cur.j+1});
        }
        return false;
    }
};

방법 2

설명

위에서 설명한 것을 DP 방식으로 푼 것이다.

시간 복잡도

O(\(NM\))

코드

struct P {int i, j, k;};
class Solution {
public:
    bool dp[102][102] = {0,};
    bool isInterleave(string s1, string s2, string s3) {
		dp[0][0] = true;
        if(s1.size() + s2.size() != s3.size()) return false;
		for(int i = 0; i <= s1.size(); i++)
			for (int j = 0; j <= s2.size(); j++)			
				if (dp[i][j])
				{
					if (s1[i] == s3[i + j]) dp[i + 1][j] = true;
					if (s2[j] == s3[i + j]) dp[i][j + 1] = true;
				}			

		return dp[s1.size()][s2.size()];
	}
};

1차원

class Solution {
public:
    bool dp[102] = {0,}; 
    bool isInterleave(const string& s1, const string& s2, const string& s3) {
        if(s1.size() + s2.size() != s3.size()) return false;
        dp[0] = true;
        
		for(int i = 0; i <= s1.size(); i++)
			for (int j = 0; j <= s2.size(); j++)			
				if (dp[j])
				{
					if (s2[j] == s3[i + j]) dp[j + 1] = true;
					dp[j] = s1[i] == s3[i + j]; 
				}			
	
		return dp[s2.size()];
	}
};

댓글남기기