Учитывая две строки s
и p
, вернуть массив всех начальных индексовp
анаграмм вs
. Вы можете вернуть ответ в любом порядке.
Анаграмма – это слово или фраза, образованная путем перестановки букв другого слова или фразы, обычно с использованием всех исходных букв ровно один раз.
Пример 1:
Input: s = "cbaebabacd", p = "abc" Output: [0,6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc".
Пример 2:
Input: s = "abab", p = "ab" Output: [0,1,2] Explanation: The substring with start index = 0 is "ab", which is an anagram of "ab". The substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start index = 2 is "ab", which is an anagram of "ab".
Ограничения:
1 <= s.length, p.length <= 3 * 104
s
иp
состоят из строчных английских букв.
Решение —
Но если вы внимательно пронаблюдаете, о чем говорит вопрос, вы обнаружите это. В строке от «a до z» присутствует строчный английский алфавит.
Поскольку диапазон указан, нет необходимости использовать HashMap. Потому что в HashMap любой символ присутствует ч/б «a-z». Ему все равно, и он даст вам ответ за O(N).
Но мы дали это, символы из «a-z», we won't use HashMap there is much better way to solve this problem.
Что мы сделаем, так это создадим 2 массива. Массив1 для строки s и Массив2 для строки p. И их размер будет 26. что они хранят частоту строки s и строки p.
- Наша первая задача — сохранить частоту строки p.
- Таким образом, a count — это 1 раз, когда мы обновляем частоту a в массиве, b count — это 1 раз, когда мы обновляем частоту b в массиве и c, а количество равно 1 разу, когда мы обновляем частоту c в массиве.
If let's say
есть еще c, в дальнейшем мы изменим его частоту до 2. - Длина "p" равна 3, мы сохраним ее длину, скажем, в переменной "m", и тем самым мы возьмем 3 символа из строки "s" и обновим их частота в массиве 1 (с)
Теперь мы сравним оба массива размером 26! Они равны? Да, они равны с одинаковой частотой появления одного и того же символа. Таким образом, it's an anagram at index 0
- Теперь, что мы будем делать, создадим 2 указателя. 1-й указатель синего цвета в 0-м индексе, работа которого заключается в исключении [уменьшении] частоты. 2-й указатель красного цвета в 3-м индексе, работа которого состоит в том, чтобы включать [приращение] частоты.
- Тем самым мы создадим постоянное окно 3 размера
- Теперь мы добавим «e» и удалим «c» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Значит, они не равны. Это не анаграмма.
- Теперь мы добавим «b» и удалим «b» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Значит, они не равны. это не анаграмма
- Теперь мы добавим «а» и удалим «а» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Значит, они не равны. это не анаграмма
- Теперь мы добавим «b» и удалим «e» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Значит, они не равны. Это не анаграмма.
- Теперь мы добавим «a» и удалим «b» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Значит, они не равны. Это не анаграмма.
- Теперь мы добавим «c» и удалим «a» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Так что да, они равны.
It's an anagram & we get it from index 6
- Теперь мы добавим «d» и удалим «b» из массива и обновим их частоту. И на каждом этапе мы должны сравнивать, равны ли они? Значит, они не равны. Это не анаграмма.
Now we will stop.
Когда красный указатель выходит за пределы массива.
И общая анаграмма, которую мы нашли, равна [ 0, 6 ]
Итак, мы нашли ее без использования HashMap. In Временная сложность BigO(N).
Я надеюсь, вы поняли, давайте закодируем это!!
class Solution { public List<Integer> findAnagrams(String s, String p) { List<Integer> list = new ArrayList<Integer>(); if(p.length() > s.length()) return list; // Base Condition int N=s.length(); // Array1 of s int M=p.length(); // Array2 of p int[]count = freq(p); // intialize only 1 time int[]currentCount = freq(s.substring(0, M)); // freq function, update every-time according to sliding window if(areSame(count,currentCount)) // areSame function list.add(0); int i; for(i=M;i<N;i++){ // going from 3 to 9 in above example currentCount[s.charAt(i-M) - 'a']--; // blue pointer, decrement frequency currentCount[s.charAt(i)-'a']++; // red pointer, increment frequency if(areSame(count,currentCount)){ // now check, both array are same list.add(i-M+1); // if we find similar add their index in our list } } return list; } private boolean areSame(int[] x, int[] y){ for(int i = 0; i < 26; i++){ if(x[i] != y[i]) // compare all the frequency & doesnn't find any di-similar frequency return true otherwise false return false; } return true; } private int[] freq(String s){ int[] count = new int[26]; // create array of size 26 for(int i = 0; i < s.length(); i++){ count[s.charAt(i) - 'a']++; // update acc. to it's frequency } return count; // and return count } }