To find the starting indices of all occurrences of the pattern in a given string, we can use the sliding window technique to compare each substring of the same length as the pattern. If we find a match, we record the starting index.
publicclassSolution {
public List<Integer>findPatternOccurrences(String string, String pattern) {
int n = string.length();
int m = pattern.length();
List<Integer> result =new ArrayList<>();
for (int i = 0; i <= n - m; i++) {
if (string.substring(i, i + m).equals(pattern)) {
result.add(i);
}
}
return result;
}
// Example usage:publicstaticvoidmain(String[] args) {
Solution solution =new Solution();
System.out.println(solution.findPatternOccurrences("abracadabra", "abr")); // Output: [0, 7] System.out.println(solution.findPatternOccurrences("aaaaa", "aa")); // Output: [0, 1, 2, 3] }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
deffindPatternOccurrences(self, string: str, pattern: str) -> List[int]:
n = len(string)
m = len(pattern)
result = []
for i in range(n - m +1):
if string[i:i + m] == pattern:
result.append(i)
return result
# Example usage:solution = Solution()
print(solution.findPatternOccurrences("abracadabra", "abr")) # Output: [0, 7]print(solution.findPatternOccurrences("aaaaa", "aa")) # Output: [0, 1, 2, 3]
⏰ Time complexity: O((n - m + 1) * m) where n is the length of the string and m is the length of the pattern. This is because we compare m characters for each of the n - m + 1 windows.
To find the starting indices of all occurrences of the pattern in a given string efficiently, we can use the Rabin-Karp algorithm, which applies a rolling hash approach. This method reduces the average-case time complexity for pattern matching.
publicclassSolution {
privatestaticfinalint BASE = 256;
privatestaticfinalint PRIME = 101;
public List<Integer>findPatternOccurrences(String string, String pattern) {
int n = string.length();
int m = pattern.length();
if (m > n) {
returnnew ArrayList<>();
}
int patternHash = hashValue(pattern, m);
int currentHash = hashValue(string, m);
List<Integer> result =new ArrayList<>();
for (int i = 0; i <= n - m; i++) {
if (currentHash == patternHash) {
if (string.substring(i, i + m).equals(pattern)) {
result.add(i);
}
}
if (i < n - m) {
currentHash = (currentHash * BASE - string.charAt(i) * pow(BASE, m) + string.charAt(i + m)) % PRIME;
if (currentHash < 0) {
currentHash += PRIME;
}
}
}
return result;
}
privateinthashValue(String s, int length) {
int hash = 0;
for (int i = 0; i < length; i++) {
hash = (hash * BASE + s.charAt(i)) % PRIME;
}
return hash;
}
privateintpow(int base, int exponent) {
int result = 1;
for (int i = 0; i < exponent; i++) {
result = (result * base) % PRIME;
}
return result;
}
// Example usage:publicstaticvoidmain(String[] args) {
Solution solution =new Solution();
System.out.println(solution.findPatternOccurrences("abracadabra", "abr")); // Output: [0, 7] System.out.println(solution.findPatternOccurrences("aaaaa", "aa")); // Output: [0, 1, 2, 3] }
}
classSolution:
deffindPatternOccurrences(self, string: str, pattern: str) -> List[int]:
n = len(string)
m = len(pattern)
if m > n:
return []
base =256 prime =101defhash_value(s: str, length: int) -> int:
h =0for i in range(length):
h = (h * base + ord(s[i])) % prime
return h
pattern_hash = hash_value(pattern, m)
current_hash = hash_value(string, m)
result = []
for i in range(n - m +1):
if current_hash == pattern_hash:
if string[i:i + m] == pattern:
result.append(i)
if i < n - m:
current_hash = (current_hash * base - ord(string[i]) * base ** m + ord(string[i + m])) % prime
if current_hash <0:
current_hash += prime
return result
⏰ Time complexity: O(n + m) on average, where n is the length of the string and m is the length of the pattern. Hashing and comparison take constant time on average.
🧺 Space complexity: O(1) for the rolling hash implementation, excluding the storage for the result list.