gpt4 book ai didi

java - 在另一个字符串中查找字符串的 Anagrams 的最佳算法

转载 作者:行者123 更新时间:2023-12-02 01:07:48 26 4
gpt4 key购买 nike

我在 Cracking The Coding Interview 书中遇到了这个主题。挑战在于找到给定的较小字符串 s 在较大字符串 b 中的排列。我可以提出以下算法,其时间复杂度为 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),即没有任何循环。这可能吗?或者有没有其他方法可以实现最优算法?

最佳答案

该算法以线性时间运行。如果您正在准备面试,那么您可能可以自己了解这里发生了什么;)

public class Solver {

List<Integer> solve(String t, String s) {

HashMap<Character, Integer> charCountInT = new HashMap<>();
for (int i = 0; i < t.length(); i++) {
Character c = t.charAt(i);
if (charCountInT.containsKey(c)) {
charCountInT.put(c, charCountInT.get(c) + 1);
}
else {
charCountInT.put(c, 1);
}
}

HashMap<Character, Integer> extraCharacters = new HashMap<>();
for (Character c : charCountInT.keySet()) {
extraCharacters.put(c, -charCountInT.get(c));
}
for (int i = 0; i < t.length(); i++) {
Character c = s.charAt(i);
if (extraCharacters.containsKey(c)) {
extraCharacters.put(c, extraCharacters.get(c) + 1);
}
}

int expectedZeroesInExtraCharacters = charCountInT.size();
int zeroesInExtraCharacters = 0;
for (Integer count : extraCharacters.values()) {
if (count == 0) ++zeroesInExtraCharacters;
}

List<Integer> answer = new ArrayList<>();
if (zeroesInExtraCharacters == expectedZeroesInExtraCharacters) answer.add(0);

for (int i = 1; i < s.length() - t.length(); i++) {

Character nextChar = s.charAt(t.length() + i - 1);
if (charCountInT.containsKey(nextChar)) {
extraCharacters.put(nextChar, extraCharacters.get(nextChar) + 1);
if (extraCharacters.get(nextChar) == 0) ++zeroesInExtraCharacters;
if (extraCharacters.get(nextChar) == 1) --zeroesInExtraCharacters;
}

Character removedChar = s.charAt(i - 1);
if (charCountInT.containsKey(removedChar)) {
extraCharacters.put(removedChar, extraCharacters.get(removedChar) - 1);
if (extraCharacters.get(removedChar) == 0) ++zeroesInExtraCharacters;
if (extraCharacters.get(removedChar) == -1) --zeroesInExtraCharacters;
}

if (zeroesInExtraCharacters == expectedZeroesInExtraCharacters) answer.add(i);
}

return answer;

}

public static void main(String[] args) {
String t = "abbc";
String s = "cbabadcbbabbcbabaabccbabc";
List<Integer> startIndices = new Solver().solve(t, s);
System.out.println(startIndices);
for (int startIndex : startIndices) {
System.out.println(s.substring(startIndex, startIndex + t.length()));
}
}

}

关于java - 在另一个字符串中查找字符串的 Anagrams 的最佳算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59799865/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com