Java | LeetCode
6.96K subscribers
198 photos
1.14K links
Cайт easyoffer.ru
Реклама @easyoffer_adv
ВП @easyoffer_vp

Тесты t.me/+icUwivvbGOkwNWRi
Вопросы собесов t.me/+7ESm0VKXC4tjYzky
Вакансии t.me/+4pspF5nDjgM4MjQy
Download Telegram
Задача: №30. Substring with Concatenation of All Words
Сложность: hard

Дана строка s и массив строк words, все слова одинаковой длины.
Нужно найти все стартовые индексы подстрок в s, которые являются конкатенацией всех слов из массива (в любом порядке и без повторов).
Верните список индексов, где такие подстроки начинаются.

Пример:
Input: s = "barfoothefoobarman", words = ["foo","bar"] Output: [0,9]


👨‍💻 Алгоритм:

1⃣Создать карту частот mapOfWords для слов из words, а также массив arr для подсчета символов всех слов (предварительная фильтрация).

2⃣Использовать скользящее окно длиной totalLen = k * words.length, где k — длина одного слова. На каждом шаге сравнивать текущую подстроку с шаблоном.

3⃣Проверить:
- Совпадают ли символы (arr стал нулевым по всем позициям).
- Можно ли разбить подстроку на слова, соответствующие words, без нарушений частоты и порядка.

😎 Решение:
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> answer = new ArrayList<>();
HashMap<String, Integer> mapOfWords = new HashMap<>();
for (String word : words) mapOfWords.put(word, mapOfWords.getOrDefault(word, 0) + 1);

int k = words[0].length();
int n = words.length * k;
int sLen = s.length();
if (sLen < n) return answer;

int[] arr = new int[26];
for (String word : words) {
for (int i = 0; i < k; i++) {
arr[word.charAt(i) - 'a']++;
}
}

int start = 0, end = n - 1;
for (int i = 0; i <= end; i++) arr[s.charAt(i) - 'a']--;

while (end < s.length() - 1) {
if (allZeros(arr) && validWords(s.substring(start, end + 1), new HashMap<>(mapOfWords), k)) {
answer.add(start);
}
arr[s.charAt(start++) - 'a']++;
arr[s.charAt(++end) - 'a']--;
}

if (allZeros(arr) && validWords(s.substring(start, end + 1), new HashMap<>(mapOfWords), k)) {
answer.add(start);
}

return answer;
}

public boolean allZeros(int[] arr) {
return Arrays.stream(arr).allMatch(i -> i == 0);
}

public boolean validWords(String s, HashMap<String, Integer> mapOfWords, int k) {
for (int i = 0; i * k < s.length(); i++) {
String current = s.substring(i * k, (i + 1) * k);
if (!mapOfWords.containsKey(current) || mapOfWords.get(current) == 0) return false;
mapOfWords.put(current, mapOfWords.get(current) - 1);
}
return true;
}
}


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM