Question
Given two strings s and t which consist of only lowercase letters.
String t is generated by random shuffling string s and then add one more letter at a random position.
Find the letter that was added in t.
Example:
Input:
s = "abcd"
t = "abcde"
Output:
e
Explanation:
'e' is the letter that was added.
Algorithm
看到這一題,第一反應就是用hashmap來做,看答案也有用位運算來做的
- hashmap
- 位運算(利用兩個相同的數異或爲0的特性)
從提交結果來看,C++兩者相差不大,位運算的內存消耗稍微少一點。運算速度我預想是hashmap要比位運算快一點,因爲位運算要遍歷完t中所有的字符纔會有結果,而hashmap可以在找到多的字符的時候就立刻返回結果,但是從提交結果來看兩者用時相差不大。
Java使用HashMap用時很不理想,只擊敗了18.75%的用戶,因爲我使用的是HashMap
這個類,而他沒有像C++那樣,可以將key對應的value自加一(++),而是要先用get取出value,再加1,並且還要判斷HashMap中是否包含key,這樣就多出了接近O(n)+O(logn)的操作數。另外:(以下描述並不嚴謹,實際的實現原理其實是比較複雜的,如有錯誤,也請指出)
- C++中的
unordered_map
實現原理是hash_table,查找元素的時間複雜度爲O(1) - Java中的
HashMap
的實現原理是紅黑樹(超過閾值的時候),查找元素的時間複雜度最好爲O(1),最差爲O(n)
優化的方法也很簡單,因爲字母就26個,所以改用數組去模擬hashmap就能優化時間
Code
C++
hashmap(unordered_map)
class Solution {
public:
char findTheDifference(string s, string t) {
unordered_map<char, int> hash;
for(auto i : s){
hash[i]++;
}
for(auto i : t){
if (hash[i] == 0)
return i;
hash[i]--;
}
return 0;
}
};
位運算-異或
class Solution {
public:
char findTheDifference(string s, string t) {
int res = 0;
for (auto i : s)
res^=i;
for (auto i: t)
res^=i;
return res;
}
};
Java
HashMap,擊敗18.75%的用戶
class Solution {
public char findTheDifference(String s, String t) {
HashMap<Character, Integer> hash = new HashMap<Character, Integer>();
for(Character i : s.toCharArray()){
if(hash.containsKey(i))
hash.put(i, hash.get(i)+1);
else
hash.put(i,1);
}
for(Character i : t.toCharArray()){
if (!hash.containsKey(i) || hash.get(i) == 0)
return i;
else
hash.put(i, hash.get(i)-1);;
}
return 0;
}
}
數組
class Solution {
public char findTheDifference(String s, String t) {
int[] hash = new int[26];
for (char i : s.toCharArray())
hash[i - 'a']++;
for (char i : t.toCharArray()){
if (hash[i - 'a'] == 0)
return i;
else
hash[i - 'a']--;
}
return 0;
}
}