728x90
반응형
문제 설명
1. 문장 s 와 단어들이 배열로 주어진다.
2. 단어들을 붙여서 s의 내부 문장을 만들 수 있으면 그 시작점을 구하면 된다.
3. 순서는 상관없지만 단어들은 딱 붙어 있어야 한다.
풀이 과정
1. 슬라이딩 윈도우 + 해시맵
2. 진짜 오래 헤맸다. 그리고 풀이 방법을 생각해내기는 했는데 솔직히 좀 더럽게 푼 느낌이다.
3. 중요한 점은, words 의 내부 단어들의 길이는 같다는 것
4. 만들어진 단어들을 앞에는 빼고 뒤에는 더하면서 비교하면 구할 수 있다.
5. 그래서 words 배열의 길이만큼 시작점을 가진 슬라이딩 윈도우 풀이를 만들어주면 된다.
코드
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
int wordLeng = words[0].length();
int wholeLeng = words.length * wordLeng;
// 최초 없는 경우 체크
if (s == null || s.length() == 0 || words == null || words.length == 0 || s.length() < words.length || s.length() < wholeLeng) {
return new ArrayList<>();
}
// 정답 확인
List<Integer> ans = new ArrayList<>();
// words 들의 등장 빈도를 체크하는 HashMap 생성
HashMap<String, Integer> wordsMap = new HashMap<>();
for(String word : words) wordsMap.put(word, wordsMap.getOrDefault(word, 0) + 1);
// 문자를 확인하는 지점의 시작점 -> 처음부터, 한칸 띄고, ... 이거를 전체 배열의 크기만큼 해주면 된다.
// 이렇게 한 이유는 단어를 하나씩 만들고 빼면서 구하기 위함이다.
for(int i=0; i<wordLeng; i++) {
int delete = i; // 맨 앞 단어 삭제를 위함
int createCnt = (s.length() - i) / wordLeng; // 현재 문자열에서 만들 수 있는 총 개수
HashMap<String, Integer> compareMap = new HashMap<>(); // s 에서 만들어낸 등장 빈도를 체크하는 해시맵
// 처음에 words 길이만큼 HashMap 채워준다
// 뒤의 and 조건 추가 이유는 이렇게 만들어진 값이 s를 넘어가는 경우 진행할 수 없기 때문이다.
for(int j=0; j<words.length && (j+1) * wordLeng + i <= s.length(); j++) {
int from = i + j * wordLeng;
int to = (j+1) * wordLeng + i;
String now = s.substring(from, to);
compareMap.put(now, compareMap.getOrDefault(now, 0) + 1);
}
if(wordsMap.equals(compareMap)) ans.add(i); // 최초 지점에 대한 비교
// 그 다음부터 슬라이딩 윈도우를 통해 단어를 하나씩 빼고 더하면서 비교해준다.
for(int j=words.length; j<createCnt; j++) {
String deleteKey = s.substring(delete, delete+wordLeng);
int newVal = compareMap.get(deleteKey) - 1;
if(newVal > 0) compareMap.put(deleteKey, newVal);
else compareMap.remove(deleteKey);
delete+=wordLeng;
int from = i + j * wordLeng;
int to = (j+1) * wordLeng + i;
String now = s.substring(from, to);
compareMap.put(now, compareMap.getOrDefault(now, 0) + 1);
if(wordsMap.equals(compareMap)) ans.add(i + ((j-words.length+1)*wordLeng));
}
}
return ans;
}
}
반응형
'알고리즘 공부' 카테고리의 다른 글
[leetcode - 3. Longest Substring Without Repeating Characters] java (1) | 2025.02.09 |
---|---|
[leetcode - 209. Minimum Size Subarray Sum] java (0) | 2025.02.07 |
[leetcode - 15. 3Sum] java (0) | 2025.02.07 |
[leetcode - 11. Container With Most Water] java (0) | 2025.02.05 |
[leetcode - 167. Two Sum II - Input Array Is Sorted] java (0) | 2025.02.05 |