今天瀏覽文章"一次谷歌面試趣事"時,看到作者分享的一道字符串題目. 具體內容如下
問題描述
假設這有一個各種字母組成的字符串,假設這還有另外一個字符串,而且這個字符串里的字母數相對少一些。從算法是講,什么方法能最快的查出所有小字符串里的字母在大字符串里都有?
比如,如果是下面兩個字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOM
答案是true,所有在string2里的字母string1也都有。如果是下面兩個字符串:
String 1: ABCDEFGHLMNOPQRS
String 2: DCGSRQPOZ
答案是false,因為第二個字符串里的Z字母不在第一個字符串里。
解題思路:
方案一:采用HashMap
采用HashMap存儲較長字符串中字符與次數對應關系.其中只要HashMap包含字符,則繼續遍歷,無需給次數加1. 因為題目中字符串都是由字母組成,所以當HashMap的長度等於26時,就可以停止遍歷較長字符串的字符.接着遍歷較短字符串的字符,如果字符都包含於HashMap,返回true;否則,返回false;
方案二:采用位運算
首先可以判斷最長字符串長度,如果特別長,可以考慮分段來處理.剛試着寫了一下代碼,字符串沒有進行分段處理.
public class IsAllInLongString {
public static boolean isAllInLongString(String longStr, String shortStr) {
/**
* 考慮輸入中有一個或兩個參數為null的情況
*/
if (longStr == null && shortStr == null || longStr == null
&& shortStr != null || longStr != null && shortStr == null) {
return true;
}
if (longStr.length() < shortStr.length()) {
String tempString = longStr;
longStr = shortStr;
shortStr = tempString;
}
/**
* 最短字符串為0,直接返回true;
*/
if (shortStr.length() == 0) {
return true;
}
int longBit = 0;
int shortBit = 0;
for (int i = 0; i < longStr.length(); i++) {
longBit |= 1 << (longStr.charAt(i) - 'a');
}
for (int i = 0; i < shortStr.length(); i++) {
shortBit |= 1 << (shortStr.charAt(i) - 'a');
}
int temp = longBit & shortBit;
/**
* 統計temp和shortBit中二進制一的個數
* 如果相等,返回true 否則,返回false
*/
if (getNumsOfOneInBinary(temp) == getNumsOfOneInBinary(shortBit)) {
return true;
}
return false;
}
/**
* 統計正整數二進制出現一的個數
*
* @param num
* @return
*/
public static int getNumsOfOneInBinary(int num) {
if (num < 0) {
throw new IllegalArgumentException("argument < 0");
}
int count = 0;
while (num != 0) {
count++;
num &= (num - 1);
}
return count;
}
public static void main(String[] args) {
System.out.println(isAllInLongString("hello", "hello world"));
}
}
寫在最后
想法寫出來才能知道對不對,有考慮不足的地方,謝謝大家的指點
