30Day LeetCoding Callenge — Week1

前端野人
·
·
IPFS
·


30-Day Leecodeing Callenge ,第一週挑戰 !!

藉由此活動,我想更深入去瞭解JavaScript的演算法思維,目標是訓練出腦海中能觀想出演算法模型。

總結這週的技巧,有兩個值得注意的演算法。

1.Hashmap

javascript 的 hashmap 就是應用Object的索引值存跨索引值得值

可參考

1.Single Number

6.Group Anagrams

7.Counting Elements

大致觀念是這樣:

let arr = ['a','b','c']
let hashmap = {}
for(let i = 0; i < arr.length ; i++){
    if(arr[i] = 'a') arr[arr[i]] = 1
}
// hashmap = { {'a': 1} }

2.two pointers

就是從陣列兩端開始走訪,直到兩端交錯

可參考:

4.Move Zeroes

GreeksforGreeks — Two Pointers Technique

let i = 0
let j = arr.length
while(i < j){
    if(condition){ 
      dosomething
    }
    i++
    j--
}

題目

1.Single Number

說明:找出陣列中不重複的數字

Example 1:

Input: [2,2,1]
Output: 1

Example 2:

Input: [4,1,2,1,2]
Output: 4

思維

我的解法是先累計每個數字的數目,然後再找數目唯一的數字

先用Object 紀錄最後再轉Array 處理,算是蠻常用到的技巧

Answer:

var singleNumber = function(nums) {
    let temp = {}
    
    nums.map(num => {
        if(!temp[num]){
            temp[num] = 1
        }else{
            temp[num] +=1
        }
    })
    return Object.keys(temp).find(key => 1 === temp[key])
};

2. Happy Number

說明:判斷是否為快樂數

Example:

Input: 19
Output: true
Explanation: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

思維

  1. 歸納出不快樂數比對輸入數字
  2. 判斷數字拆開相乘的數是不是快樂數,然後回到1.判斷是否快樂

Answer

var isHappy = function(n) {
    let answer = false
    let notHappy = [4,,16,37,58,89,145,42,20]
    let num = n
    while(notHappy.indexOf(num) === -1){
        if(num ===1){
            answer = true
            break
        }else{
           let list =  num.toString().split("")
           let sum = 0
           let newNum = list.map((a)=>{
              return sum += Math.pow(a,2) 
           })
           num = sum
        }
    }
    
    return answer
};

3.Maximum Subarray

說明:找出陣列中連續加總最大和

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

思維:

這題目有點抽象,首先先找出最大值,然後加總為負數則設為0

我後來想想如果最大和是負數該怎麼辦?如果是這樣的話那最大值應該就是最大和了,

所以小於0就等於0比較像是連續陣列的斷點,用這樣想比較好懂

Answer

var maxSubArray = function(nums) {
    let max = Math.max(...nums)
    let num = 0
    
    for(let i = 0 ; i < nums.length ; i++){
        num += nums[i]
        if(num > max) max = num
        if(num < 0) num = 0 
    }
    
    return max
};

4.Move Zeroes

說明:把所有0移到最後面

Example:

Input: [0,1,0,3,12]
Output: [1,3,12,0,0]

思維

題目有提示適合用two pointer , two pointer 是簡單好用的演算法

看題目就可以知道,這個演算法就是從兩頭開始比對直到交錯為止,

陣列右邊(尾端)是放0得地方,所以遇到0就向左走

陣列左邊(頭端)是移動0的地方,所以用splice(i,1)切掉0,在push(0)

Answer

var moveZeroes = function(nums) {
    let i = 0
    let j = nums.length - 1
    
    while(i < j ){
        if(nums[j] === 0) j--
        if(nums[i] === 0) {
            nums.splice(i,1)
            nums.push(0) 
        }else{
            i++
        }
    }
  
};

5.Best Time to Buy and Sell Stock II

說明:股票陣列中找出最大收益和

Example 1:

Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
             Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.

Example 2:

Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
             Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
             engaging multiple transactions at the same time. You must sell before buying again.

Example 3:

Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

思維

這題沒有很複雜,題目有說明都是單次交易所以只要當天比隔天還低就是賺

Answer

var maxProfit = function(prices) {
    let i = 0
    let j = prices.length
let sumProfit = 0
    
    while(i < j-1 ){
        let profit = 0
        if(prices[i] < prices[i+1] ){
            profit = prices[i+1]- prices[i]
        }
        sumProfit += profit
        
        i++
    }
    
    return sumProfit
};

6.Group Anagrams

說明:找出字母一樣的單字並分類

Example:

Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

思維

這題難在於輸入跟輸出的陣列是非對稱的,所以有時要嘗試 hashmap

string.split(‘’).sort()則是用來判斷是否同類

Answer:

var groupAnagrams = function(strs) {
    
    let hash = {
    }
    
    strs.map(s =>{
        let temp = ""
        let math = s.split('').sort()
        if(temp !== math) temp = math
        if(temp === math){
            if(hash[math]){
                   hash[math].push(s) 
            }else{
                hash[math] = [s]
            }
        }
     })
    
  return (Object.values(hash))
    
};

7.Counting Elements

說明:計算陣列中存在 n+1 的數。

Example 1:

Input: arr = [1,2,3]
Output: 2
Explanation: 1 and 2 are counted cause 2 and 3 are in arr.

Example 2:

Input: arr = [1,1,3,3,5,5,7,7]
Output: 0
Explanation: No numbers are counted, cause there's no 2, 4, 6, or 8 in arr.

Example 3:

Input: arr = [1,3,2,3,5,0]
Output: 3
Explanation: 0, 1 and 2 are counted cause 1, 2 and 3 are in arr.

Example 4:

Input: arr = [1,1,2,2]
Output: 2
Explanation: Two 1s are counted cause 2 is in arr.

思維:hashmap的變形應用

  1. 找出有沒有n+1的數,並累計有幾個
  2. 再找一次陣列中的值有幾個符合n+1
  3. 累加hashmap裡面符合n+1的數量

Answer

var countElements = function(arr) {
    let hash = {}
    arr.map(num => {
      if(!hash[num +1 ]){
          hash[num +1 ] = 1
      } else{
           hash[num +1 ] += 1
      }
    })
let index =  Object.keys(hash).filter((h,i) =>{
      return arr.some(a =>{
           return  a == h
        })
    })
    
    let answer = 0
    index.map((i) =>{
        answer += hash[i]
    })
    return answer
};
CC BY-NC-ND 2.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!