문제 링크

요약

  • 다음에 다시 풀어보기

최종

  • 어차피 나중에 다시 풀어봐야되니까 key idea 만 간단하게 적어보면:
    • word1word2 에 pointer 를 하나씩 두고 character 를 앞에서부터 매칭할거다.
    • 두 pointer 가 가리키는 놈이 같으면 그냥 매칭시키고 두 포인터를 옆으로 움직이면 된다.
    • 근데 다르면 문제가 된다: 하나 있는 free change 기회를 소진해서 매칭시킬까 말까를 정해야 된다.
      • 만약 지금 소진했는데, 뒤에서 또 필요한 경우가 생기면 안되니까 언제 쓸지를 고민해야 하는데 이걸 알아내는 방법은 suffix match 를 활용하는거다.
        • suffix_match[i]word1[i+1:] 의 substring 에 대해 word2 와 매칭되는 character 가 얼마나 있냐를 저장한다.
      • 즉, 지금까지 매칭한 수 + 1 (지금 free change 사용해서 매칭) + suffix_match[i] (이후로 매칭될 개수) 를 확인하면 지금 free change 를 사용했을 때 뒤에서는 free change 없이 전부 매칭할 수 있는지를 알 수 있게 된다.
class Solution {
public:
	vector<int> validSequence(string word1, string word2) {
		int n1 = word1.size();
		int n2 = word2.size();
		vector<int> suffix_match(n1);
		vector<int> ret(n2);
 
		{
			int i2 = n2 - 1;
			int matched = 0;
			for (int i1 = n1 - 1; 0 <= i1; i1--) {
				suffix_match[i1] = matched;
 
				if (0 <= i2 && word1[i1] == word2[i2]) {
					i2--;
					matched++;
				}
			}
		}
 
		{
			int i2 = 0;
			int matched = 0;
			bool changed = false;
			for (int i1 = 0; i1 < n1 && i2 < n2; i1++) {
				if (word1[i1] != word2[i2]) {
					if (!changed && (matched + suffix_match[i1] + 1 >= n2)) {
						ret[i2] = i1;
						i2++;
						matched++;
						changed = true;
					}
				} else {
					ret[i2] = i1;
					i2++;
					matched++;
				}
			}
 
			if (matched != n2) {
				return {};
			}
		}
 
		return ret;
	}
};

삽질 기록

DP

  • 2D DP 로 해봤는데 이어서 터진다.