【发布时间】:2020-01-18 10:55:03
【问题描述】:
我在 Cracking The Coding Interview 一书中遇到了这个话题。挑战是在较大的字符串 b 中找到给定的较小字符串 s 的排列。我可以提出以下算法,其时间复杂度为 O(B x S),其中 S 和 B 分别是给定较小和较大字符串的长度:
import java.util.HashMap;
public class AnagramAlgorithm {
public static void main(String[] args) {
String s = "cbabadcbbabbcbabaabccbabc";
String b = "abbc";
printAnagramsOfB(s, b);
}
public static void printAnagramsOfB(String text, String pattern) {
if(isEmpty(text) || isEmpty(pattern)) {
System.out.println("Invalid Strings");
return;
}
int patternLength = pattern.length();
for (int i = 0; i < text.length() - patternLength + 1; i++) {
String substring = text.substring(i, i + patternLength);
if (isAnagram(pattern, substring)) {
System.out.println("Anagram Found : " + substring);
}
}
}
public static boolean isEmpty(CharSequence str) {
return str == null || str.length() == 0;
}
public static boolean isAnagram(String pattern, String substring) {
if (pattern.length() != substring.length()) {
System.out.println("SubString length doesn't match the length of Given String");
return false;
}
char[] subStringArr = substring.toCharArray();
char[] patternArr = pattern.toCharArray();
HashMap<Character, Integer> mapPattern = new HashMap<>();
HashMap<Character, Integer> mapSubstring = new HashMap<>();
for (int i = 0; i < subStringArr.length; i++) {
if (mapSubstring.containsKey(subStringArr[i])) {
int count = mapSubstring.get(subStringArr[i]);
mapSubstring.put(subStringArr[i], count + 1);
} else {
mapSubstring.put(subStringArr[i], 1);
}
if (mapPattern.containsKey(patternArr[i])) {
int count = mapPattern.get(patternArr[i]);
mapPattern.put(patternArr[i], count + 1);
} else {
mapPattern.put(patternArr[i], 1);
}
}
return mapPattern.equals(mapSubstring);
}
}
书中提到最优算法是 O(B)。我想不出这样的算法。根据我的想法,对于整体复杂度为 O(B),查找子字符串是否为字谜的算法应该是 O(1),即没有任何循环。这甚至可能吗?或者有没有其他方法可以实现最优算法?
【问题讨论】:
标签: java algorithm data-structures