단어 목록이 있다고 가정합니다. 여기에서 각 단어는 소문자로 구성됩니다. 따라서 한 단어 word1은 word2와 같게 만들기 위해 word1의 아무 곳에나 정확히 하나의 문자를 추가할 수 있는 경우에만 다른 단어 word2의 선행자입니다. 예를 들어 "abc"는 "abac"의 선행자입니다. 이제 단어 체인은 k>=1인 단어 [word_1, word_2, ..., word_k]의 시퀀스입니다. 여기서 word_1은 word_2의 선행 항목이고, word_2는 word_3의 선행 항목입니다. 주어진 단어 목록에서 선택한 단어를 사용하여 단어 체인의 가능한 가장 긴 길이를 찾아야 합니다.
따라서 입력이 ["a","b","ba","bca","bda","bdca"]와 같으면 가장 긴 체인 중 하나가 [" a", "ba", "bda", "bdca"].
이 문제를 해결하기 위해 다음 단계를 따릅니다. −
-
맵 정의 dp, n :=단어 배열의 크기
-
길이에 따라 단어 배열 정렬
-
ret :=0
-
0 tn n – 1 범위의 i에 대해
-
최고 :=0
-
범위 0에서 단어[i] – 1의 길이까지의 j에 대해
-
word :=(단어[i]의 부분 문자열 0에서 j – 1) 연결(단어[i]의 부분 문자열 j + 1에서 끝까지)
-
최고 :=최고의 최대값, dp[단어] + 1
-
-
dp[단어[i]] :=최고
-
ret :=최대 (ret, dp[단어[i]])
-
-
리턴 렛
이해를 돕기 위해 다음 구현을 살펴보겠습니다. −
예
#include <bits/stdc++.h> using namespace std; class Solution { public: static bool cmp(string s1, string s2){ return s1.size() < s2.size(); } int longestStrChain(vector<string>& words) { unordered_map <string, int> dp; int n = words.size(); sort(words.begin(), words.end(), cmp); int ret = 0; for(int i = 0; i < n; i++){ int best = 0; for(int j = 0; j < words[i].size(); j++){ string word = words[i].substr(0, j) + words[i].substr(j + 1); best = max(best, dp[word] + 1); } dp[words[i]] = best; ret = max(ret, dp[words[i]]); } return ret; } }; main(){ vector<string> v = {"a","b","ba","bca","bda","bdca"}; Solution ob; cout << (ob.longestStrChain(v)); }
입력
["a","b","ba","bca","bda","bdca"]
출력
4