넘치게 채우기

[LeetCode] 1048. Longest String Chain 본문

PS/LeetCode

[LeetCode] 1048. Longest String Chain

riveroverflow 2023. 9. 23. 15:54
728x90
반응형

https://leetcode.com/problems/longest-string-chain/description/

 

LeetCode - The World's Leading Online Programming Learning Platform

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

문제 유형 : 다이나믹 프로그래밍 / 문자열 처리

문제 난이도 : Medium

 

 

You are given an array of words where each word consists of lowercase English letters.

wordA is a predecessor of wordB if and only if we can insert exactly one letter anywhere in wordA without changing the order of the other characters to make it equal to wordB.

  • For example, "abc" is a predecessor of "abac", while "cba" is not a predecessor of "bcad".

A word chain is a sequence of words [word1, word2, ..., wordk] with k >= 1, where word1 is a predecessor of word2, word2 is a predecessor of word3, and so on. A single word is trivially a word chain with k == 1.

Return the length of the longest possible word chain with words chosen from the given list of words.

 

문자열 배열 words에는 영소문자로 구성된 단어들이 들어있다.

 

wordA의 어느 곳에 한 문자를 삽입하여  wordB 를 만들 수 있다면, wordA는 wordB의 전임자이다.

문자 체인은 앞의 단어가 뒤의 단어의 전임자로, 뒤의 단어가 앞의 단어의 전임자로 이어지는 것을 말한다.

조건을 만족하는 가장 긴 문자 체인의 길이를 반환시켜라.

 

문제 풀이

우선, words 배열을 문자가 가장 짧은순으로 정렬시킨다. 길이가 같으면 사전순으로 되게 하였다.

문자 체인을 담는 dp를 만든다. dp[i]는 i번째를 꼭 넣는 문자 체인이다.

 

배열을 순회하면서 다음 과정을 거친다:

1. 이전 체인들 중에서 연결 가능하면서 가장 긴 체인을 찾는다.

2. 그 체인에 연결한다.

3. 가장 긴 체인의 길이를 업데이트한다.

 

체인의 연결 가능 여부(전임자 확인)는 다음과 같이 한다:

1. 두 배열의 길이 차이가 1이 아니라면, 전임자 관계가 될 수 없다.

2. 두 문자열을 인덱스 0부터 비교해본다.

글자가 같으면 같이 인덱스를 더하고, 다르면 더 더 긴 문자열(후임자가 될 예정인)을 참조하는 인덱스만 1을 더한다.

3.순회가 정상적으로 끝냈는지 확인한다.

 

그 뒤, 가장 긴 길이를 반환해주면 된다.

 

코드

C++

class Solution {
public:
    bool isPredecessor(string A, string B)
    {
        int n = A.size();
        int m = B.size();

        if(m-n != 1) return false;

        int a = 0;
        int b = 0;

        while (a < n && b < m) {
        if (A[a] != B[b]) {
            b++;
        } else {
            a++;
            b++;
        }
    }

        return a == n;
    }

    int longestStrChain(vector<string>& words) {
        const int n = words.size();
        vector<vector<string>> dp(n);

        sort(words.begin(), words.end(), [](const string &a, const string &b) {
            if(a.size() == b.size()) {
                return a < b;
            }
            return a.size() < b.size();
        });

        dp[0].push_back(words[0]);

        int longestLength = -1;
        for(int i = 1; i < n; i++) {
            int idxToAppend = -1;
            int longestIdx = 0;
            for(int j = i-1; j >= 0; j--) {
                if(dp[j].size() >= longestIdx && isPredecessor(words[j], words[i])) {
                    idxToAppend = j;
                    longestIdx = dp[j].size();
                }
            }
            if(idxToAppend != -1){
                dp[i].assign(dp[idxToAppend].begin(), dp[idxToAppend].end());
            }
            dp[i].push_back(words[i]);

            longestLength = max(longestLength, static_cast<int>(dp[i].size()));
        }

        if(longestLength <= 0) {
            longestLength = 1;
        }
        return longestLength;
    }
};

 

 

728x90
반응형

'PS > LeetCode' 카테고리의 다른 글

[LeetCode] 896. Monotonic Array  (0) 2023.09.29
[LeetCode] 905. Sort Array By Parity  (0) 2023.09.28
[LeetCode] 377. Combination Sum IV  (0) 2023.09.09
[LeetCode] 141. Linked List Cycle  (0) 2023.09.04
[LeetCode] 62. Unique Paths  (0) 2023.09.03