티스토리 뷰
Problem
Given two strings s and p, return an array of all the start indices of p's anagrams in s. You may return the answer in any order.
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
Example 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".
Example 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".
Constraints:
- 1 <= s.length, p.length <= 3 * 10^4
- s and p consist of lowercase English letters.
Solution
문자열 s와 p가 주어질 때, 문자열 s에서 p로 표현할 수 있는 모든 anagram을 찾아 anagram이 시작하는 인덱스를 순서에 상관없이 반환하는 문제입니다.
anagram은 문자의 순서를 바꿔 다른 문자를 만드는 것을 말합니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Solution {
public List<Integer> findAnagrams(String s, String p) {
if (s == null) {
return Collections.emptyList();
}
int sLength = s.length();
int pLength = p.length();
if (sLength == 0 || sLength < pLength) {
return Collections.emptyList();
}
List<Integer> result = new ArrayList<>();
int[] pMap = new int[26];
int[] sMap = new int[26];
for (int i = 0; i < pLength; i++) { // (1)
pMap[p.charAt(i) - 'a']++;
}
for (int i = 0; i < pLength; i++) { // (2)
sMap[s.charAt(i) - 'a']++;
}
for (int i = 0; i < sLength - pLength; i++) { // (3)
if (isMatch(pMap, sMap)) { // (4)
result.add(i);
}
sMap[s.charAt(i + pLength) - 'a']++; // (5)
sMap[s.charAt(i) - 'a']--; // (6)
}
if (isMatch(pMap, sMap)) { // (7)
result.add(sLength - pLength);
}
return result;
}
public boolean isMatch(int[] arr1, int[] arr2) {
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
}
- p에 나타나는 알파벳의 갯수를 저장합니다.
- s에 나타나는 알파벳의 갯수를 처음부터 p의 길이만큼만 저장합니다.
- 문자열 s를 순차적으로 탐색하면서
- 두 문자열에 나타난 알파벳의 갯수가 동일한지 확인하여 동일하면 결과에 인덱스를 추가합니다.
- 다음 인덱스에 해당하는 알파벳의 갯수를 1 증가시켜주고
- 첫 번째 인덱스에 해당하는 알파벳의 갯수를 1 감소시킵니다.
- s의 마지막 문자열 중 p의 길이에 해당하는 만큼 알파벳의 갯수가 일치하는지 확인하여 결과에 마지막 인덱스까지 추가해줍니다.
Test
package io.lcalmsky.leetcode.find_all_anagram_in_a_string;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List;
import org.junit.jupiter.api.Test;
class SolutionTest {
@Test
void givenTwoStrings_whenFindAnagram_thenCorrect() {
assertAll(
() -> test("cbaebabacd", "abc", List.of(0, 6)),
() -> test("abab", "ab", List.of(0, 1, 2))
);
}
private void test(String s, String p, List<Integer> expected) {
// when
Solution findAllAnagramInAString = new Solution();
List<Integer> actual = findAllAnagramInAString.findAnagrams(s, p);
// then
assertEquals(expected, actual);
}
}
'Algorithm > LeetCode' 카테고리의 다른 글
389. Find the Difference (0) | 2022.02.14 |
---|---|
80. Remove Duplicates from Sorted Array II (0) | 2022.02.13 |
121. Best Time to Buy and Sell Stock (0) | 2022.02.06 |
189. Rotate Array (0) | 2022.02.05 |
84. Largest Rectangle in Histogram (0) | 2022.02.04 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 스프링 데이터 jpa
- 스프링부트
- 알고리즘
- @ManyToOne
- JSON
- 함께 자라기 후기
- intellij
- Spring Boot Tutorial
- spring boot app
- proto3
- 헥사고날 아키텍처
- Spring Boot JPA
- Java
- 스프링 부트 회원 가입
- Spring Data JPA
- gRPC
- spring boot jwt
- QueryDSL
- 클린 아키텍처
- Jackson
- 함께 자라기
- 스프링 부트 튜토리얼
- Spring Boot
- leetcode
- 스프링 부트 애플리케이션
- 스프링 부트
- JPA
- Linux
- r
- spring boot application
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
글 보관함