LeetCode의 문제와 유저들이 등록한 코드 중 득표수가 가장 높은 코드 분석
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
단어 사전에 저장된 단어들을 조합하여 주어진 String을 만들 수 있는지 여부 확인
Note:
- The same word in the dictionary may be reused multiple times in the segmentation. 단어 사전에 있는 단어는 중복해서 사용 가능
- You may assume the dictionary does not contain duplicate words. 단어 사전에는 중복된 단어들이 저장되어있지 않음
Example 1:
Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".
"leetcode"는 "leet code"로 만들어질 수 있으므로 true
Example 2:
Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word.
"applepenapple"는 "apple pen apple"로 만들어질 수 있으므로 true (apple 중복 사용)
Example 3:
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false
"catsandog"는 단어 사전에 있는 단어의 조합으로는 만들어질 수 없으므로 false
class Solution {
public static boolean wordBreak(String s, List<String> wordDict) {
Set<String> helper = new HashSet(wordDict);
int[] cache = new int[s.length()];
Arrays.fill(cache, -1);
int longestWord = 0;
for (String word : wordDict) {
if (word.length() > longestWord) {
longestWord = word.length();
}
}
return wordBreak(s, 0, helper, cache, longestWord);
}
private static boolean wordBreak(String s, int start, Set<String> wordDict, int[] cache, int lw) {
if (start >= s.length()) {
return true;
}
if (cache[start] != -1) {
return cache[start] == 0 ? false : true;
}
boolean result = false;
for (int i = start; i < start + lw && i < s.length(); i++) {
if (wordDict.contains(s.substring(start, i + 1))) {
result = wordBreak(s, i + 1, wordDict, cache, lw);
}
if (result) {
break;
}
}
cache[start] = result ? 1 : 0;
return result;
}
}
풀이 방법
1. 주어진 String를 처음 문자부터 잘라내어 단어 사전에 포함된 단어인지 있는지를 체크하고 없다면 잘라낼 문자의 수를 증가시킨다.
- 주어진 String이 catsandog 인 경우 c, ca, cat, cats, 단어 사전에 와 같이 문자를 잘라내어 단어 사전에서 검색
2. 단어가 사전에 포함되어있는 경우
- 문자를 만드는 시작점을 변경하여 다시 사전에서 검색한다.
- s = "catsandog", wordDict = ["dog", "sand", "cat"]인 경우 cat 이 사전에 있으므로 시작점은 cat의 다음인 s로 변경한다.
코드 동작 확인
Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
1. 문자를 조합할 때 단어장에서 가장 긴 단어의 길이를 초과할 필요가 없으므로 단어 사전에서 가장 긴 단어의 길이를 구한다.
2. 한번 계산한 결과를 저장할 배열을 생성하고 초기값을 -1로 설정한다.
3. 주어진 String를 이용하여 단어를 만들어가며 단어 사전에 포함되어 있는지 확인한다.
초기값: start = 0, cache = [-1, -1, -1,-1, -1, -1,-1, -1, -1], lwlongestWord = 4
1차 사전에 포함된 단어 확인
start = 0
i = 2
substring = "cat"
start = 3
i = 6
substring = "sand"
cache [3] = 0
start = 7
i = 8
substring = "og"
cache [7] = 0
1차 검색 실패로 2차 검색 시작
start = 0
i = 3
substring = "cats"
start = 4
i = 6
substring = "and"
start = 7
cache [7]에 결과가 저장되어 있으므로 해당 값으로 false 반환
2차 검색 실패로 3차 검색 시작
start = 0
i = 4
substring = "catsa"
만들어진 단어의 길이가 단어 사전에서 가장 긴 단어보다 길어 검색을 종료
단어 사전에 있는 단어의 조합으로 만들어 낼 수 없으므로 false를 반환
'LeedCode' 카테고리의 다른 글
[LeedCode] 617. Merge Two Binary Trees (0) | 2019.11.29 |
---|---|
[LeetCode] 56. Merge Intervals (0) | 2019.11.13 |