今天是第一次寫算法題解,其實我也是最近開始刷題,以前也沒這習慣。程序員刷題就像是煎餅大叔煎餅,一天不煎幾十個感受無法在這行混了。我之因此開始刷題是由於好些大廠的朋友都有這習慣,我忽然意識到,像我這種不刷題還能習覺得常的狀況真的是好多啊!大廠之因此是大廠,是由於別人是真的在煎餅,而我這種,只是煎餅大叔的收銀員啊!程序員
既然是第一道題,那就簡單點了!es6
題目描述:
leetcode-771.寶石與石頭web
給定字符串J 表明石頭中寶石的類型,和字符串 S表明你擁有的石頭。S 中每一個字符表明了一種你擁有的石頭的類型,你想知道你擁有的石頭中有多少是寶石。算法
J 中的字母不重複,J 和 S中的全部字符都是字母。字母區分大小寫,所以"a"和"A"是不一樣類型的石頭。數組
示例 1:微信
輸入: J = "aA", S = "aAAbbbb" 輸出: 3 示例 2:編輯器
輸入: J = "z", S = "ZZ" 輸出: 0 注意:url
S 和 J 最多含有50個字母。J 中的字符不重複。spa
題解:
這個題,大部分人會解,通常作法是這樣:.net
/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function(jewels, stones) {
jewels = jewels.split('');
return stones.split('').reduce((prev, val) => {
for (const ch of jewels) {
if (ch === val) {
return prev + 1;
}
}
return prev;
}, 0);
};
思路就是把石頭每一個字符都遍歷一遍,再判斷每一個字符是不是寶石。不過這樣作的複雜度比較高,若是石頭長度是x,寶石長度是y,時間複雜度就是O(xy);
推薦解法:
/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function(J, S) {
const jewelsSet = new Set(J.split(''));
return S.split('').reduce((prev, val) => {
return prev + jewelsSet.has(val);
}, 0);
};
對比發現,最大的區別就是用到了es6的哈希集合Set。Set跟數組很像,不過它裏面沒有重複的值;將長度爲x的寶石裏的字符做爲參數構造一個Set,這個時間複雜度是O(x);再遍歷長度爲y的石頭字符串,prev + jewelsSet.has(val)這一步意思是判斷寶石中是否存在此字符,並且自動濾掉重複字符。這裏有個小技巧就是Number+ true至關因而Number+1,時間複雜度爲O(1);因此算下來複雜度就降爲O(x+y)。
從空間複雜上來看,第一個解法爲O(1),第二個爲O(x);很容易理解,前者只用存一個變量,後者用到了哈希集合,可是效率上很明顯後者更好。
水文到這裏就結束了,但願對你有用!要不要猜猜Number+ false等於多少呀?
參考連接:https://leetcode-cn.com/problems/jewels-and-stones
本文分享自微信公衆號 - 字節逆旅(wvivw_007)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。