0%

LeetCode-刷題筆記2

文章目的

想要利用系列的文章,來記錄一下自己刷 LeetCode 的解題筆記,方便日後複習。

前言

筆者在前端領域還是個小菜雞XD,目前刷題方向為 LeetCode 免費試題中難度為 Easy 的題目,刷題語言部分則是 JavaScript。

Kids With the Greatest Number of Candies


題目連結

目的

此題主要目的,有個陣列裡頭數字代表每個小孩目前擁有的糖果數,並且還有額外的糖果,想要問每個小孩拿到額外糖果後會不會成為最多糖果的人(可以同時存在擁有多個糖果的人),最後回傳含有 boolean 的陣列。

思考方向

筆者的想法是透過 map 查看每個小孩的糖果,並且為他們加上額外的糖果數,接著再利用 filter 去篩選出是否有糖果數大於已經加入額外糖果的小孩,如果有就回傳 false,沒有就回傳 true,來看一下程式碼:

1
2
3
4
5
6
7
8
const kidsWithCandies = (candies, extraCandies) => {
return candies.map((candy) => {
const combineCandy = candy + extraCandies
const arr = candies.filter(item => item > combineCandy)

return arr.length ? false : true
})
}

arr 裡存在數值,代表該小孩的糖果數即使加了額外糖果,還是有其他小孩的糖果比他多,所以我們要回傳的陣列就會給他 false,反之就是 true

更好方法

這邊透過 Math.max 可以讓程式碼更為優雅,先利用 Math.max 找出 candies 中最大的糖果數,接著透過 map 為每個糖果加上額外糖果,並檢查是否有大於等於最大糖果數,看一下程式碼:

1
2
3
4
const kidsWithCandies = (candies, extraCandies) => {
const max = Math.max(...candies)
return candies.map(candy => candy + extraCandies >= max)
}

Shuffle the Array


題目連結

目的

這題會傳入一個數字陣列與一個整數到函數中,陣列的長度會是整數的兩倍,也就是 2n,函數需要處理的是將陣列從 2n 變成 n n,並將同索引的數字連在一起產出新陣列,例如:[n1[i], n2[i], n1[i+1], n2[i+1]]

思考方向

筆者透過 filter 將數字分成兩個陣列,再透過對其中一個陣列做迴圈,把兩個陣列的同索引數字塞入新陣列中,並回傳該新陣列,來看一下程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
const shuffle = (nums, n) => {
const arr = nums.filter((item, index) => index < n)
const arr2 = nums.filter((item, index) => index >= n)
let combineArr = []

arr.forEach((item, index) => {
combineArr.push(item)
combineArr.push(arr2[index])
})

return combineArr
}

利用 n 把數字拆成兩個陣列,接著用 forEach 把兩陣列同索引的值塞入 combineArr 中。

更好方法

筆者找到一個方法,發現其實這題蠻考驗邏輯的XD。
陣列中後半段的數字對應的索引其實就是前半段索引加 n,根據這邏輯可以讓程式碼更簡潔,來看一下程式碼:

1
2
3
4
5
6
7
const shuffle = (nums, n) => {
let res = []
for (let i = 0; i < n; i++) {
res.push(nums[i], nums[i+n])
}
return res
}

透過新的方法改寫,程式碼是不是變優雅很多,而且更易理解了。

Jewels and Stones


題目連結

目的

這題我覺得蠻有趣的,你會有一堆石頭,並且你知道寶石的種類,然後要你找出石頭裡有幾種寶石。
寶石與石頭都是由英文大小寫的字串組成,每一個大寫與每一個小寫皆代表一種石頭。

思考方向

大方向來講就是找出石頭堆字串中有多少字是與寶石吻合的。
筆者想法是先將兩串文字拆出來組成兩個陣列,再用陣列去比對並算出符合的數量,接著來看看程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const numJewelsInStones = function(jewels, stones) {
const jewelsTotal = jewels.length;
const stonesTotal = stones.length;

const stonesBox = [];
for (let i = 0; i < stonesTotal; i++) {
stone = i === stonesTotal ? stones.substring(i) : stones.substring(i, i+1);
stonesBox.push(stone);
}

const jewelsBox = [];
for (let i = 0; i < jewelsTotal; i++) {
jewel = i === jewelsTotal ? jewels.substring(i) : jewels.substring(i, i+1);
jewelsBox.push(jewel);
}


let count = 0;
jewelsBox.forEach((jewel) => {
const jewelsCount = stonesBox.filter(stone => stone === jewel).length;
count += jewelsCount;
})

return count
};

更好方法

不得不說筆者對於 JS 部分的方法還不是這麼的熟練,看完別人分享的解法,真的讓我眼睛為之一亮,這邊分享一個我覺得很不錯的方法,直接來看看程式碼:

1
2
3
4
const numJewelsInStones = (J, S) => {
const jewels = new Set(J)
return S.split('').reduce((res, s) => res + jewels.has(s), 0)
};

這方法是 Setreduce 結合的應用,先將寶石種類製作成 Set,那為什麼適合這樣做?
是因為寶石每個種類皆是唯一,所以適合組成 Set 來幫我們比對。

透過 split 將字串拆成陣列(哎,當初怎麼沒想到有這招),接著透過 reduce 搜尋每一個符合的石頭並加總,這邊利用了 true 在做運算時可當作 1 的特性(false 的話會是0),因此省略了不少步驟。

短短幾行程式碼就解決了這次的問題,真是優雅啊。