10分鐘題解——寶石與石頭


今天是第一次寫算法題解,其實我也是最近開始刷題,以前也沒這習慣。程序員刷題就像是煎餅大叔煎餅,一天不煎幾十個感受無法在這行混了。我之因此開始刷題是由於好些大廠的朋友都有這習慣,我忽然意識到,像我這種不刷題還能習覺得常的狀況真的是好多啊!大廠之因此是大廠,是由於別人是真的在煎餅,而我這種,只是煎餅大叔的收銀員啊!程序員

既然是第一道題,那就簡單點了!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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索