『字節跳動LeetCode聯合周賽』--周賽185(JavaScript) | OFEII

前言

😆Hi! my name is OFEII, a Front-end Developer rookie......前端

😅Still 0 offer in this cold 2020 Spring.c++

😀菜鳥。大四前端菜鳥,20春招至今仍是0 offer(下週好像有兩個hr面了),興趣使然地刷上了LeetCode,發現用js刷算法是一件頗有趣的事,感覺到數據結構和算法的魅力所在。我愛js,我愛算法,我愛前端。web

😅可笑。本週的LeetCode周賽185是『字節LeetCode聯合周賽』,本想着刷到前300拿個字節跳動的內推面試,卻發現被各路算法dalao吊打,奈何本身太菜,規定時間內差很少才作了兩道,如今想一想真是有夠可笑面試

🙂苦練。雖然我起步晚,但這幾個月來一直在複習前端知識,查漏補缺,惡補數據結構和算法,計算機網絡,刷題,刷leetcode,寫題解,寫總結。苦練屠龍技,加油!看了不少掘金上的文章,衷心地感謝掘金這個平臺!算法

😛初露。比賽後,把今天的周賽的題又研究一下,並寫了題解總結,發佈了我在掘金上的第一篇文章。個人目標是寫一本《前端js算法-面試筆試速成大法》!雖然感受很遙遠。第一次寫文章,有不足之處請各位dalao多多指點數組

🙏許願。最後許願上海衆安保險的offer。網絡


leetcode周賽185-1:💾reformat從新格式化

題目

給你一個混合了數字和字母的字符串 s,其中的字母均爲小寫英文字母。數據結構

請你將該字符串從新格式化,使得任意兩個相鄰字符的類型都不一樣。也就是說,字母后面應該跟着數字,而數字後面應該跟着字母。ssh

請你返回 從新格式化後 的字符串;若是沒法按要求從新格式化,則返回一個 空字符串 。數據結構和算法

具體題目及示例🌰

解題思路💡

1、拼接法💾

  1. 創建兩個數組a1,a2分別存儲數字和字母,res存儲結果
  2. 遍歷一次,用Number.isFinite() 將數字和字母分類(正則也ok)
  3. 拼接字符串數組:① len2(字母) > len1(數字) 字母在前 ② 反之,數字在前
  4. 判斷返回空字符的狀況:① len1,len2均小於0 ② len1,len2之間的差值大於1

代碼📃

//1、拼接法
let reformat = (s)=> {
    let arr = s.split(''), n = arr.length
    let nArr = arr.map(e=>+e) 
    let a1 = [], a2 =[], res=[]

    for(let i = 0; i < n; i++){
        Number.isFinite(nArr[i]) ? a1.push(nArr[i]) : a2.push(arr[i])
    }
    let l1 =a1.length,l2 =a2.length

    for (let i = 0; i < n; i++) {
        l2 > l1 ? res.push(a2[i],a1[i]) : res.push(a1[i],a2[i])
    }

    return ((l1 <=0 && l2<=0 ) || Math.abs(l1-l2)>1)? "" : res.slice(0, n).join('')
};
複製代碼

leetcode周賽185-2:🍣displayTable點菜展現表

題目

給你一個數組 orders,表示客戶在餐廳中完成的訂單,確切地說, orders[i]=[customerNamei,tableNumberi,foodItemi] ,其中 customerNamei 是客戶的姓名,tableNumberi 是客戶所在餐桌的桌號,而 foodItemi 是客戶點的餐品名稱。

請你返回該餐廳的 點菜展現表 。在這張表中,表中第一行爲標題,其第一列爲餐桌桌號 「Table」 ,後面每一列都是按字母順序排列的餐品名稱。接下來每一行中的項則表示每張餐桌訂購的相應餐品數量,第一列應當填對應的桌號,後面依次填寫下單的餐品數量。

注意:客戶姓名不是點菜展現表的一部分。此外,表中的數據行應該按餐桌桌號升序排列。

具體題目及示例🌰

解題思路💡

1、hash法🍣

  1. 創建一個table(map)存儲每桌的菜品數量,一個foods(set)存儲菜單上菜品(食物)的種類,res存儲結果
  2. 遍歷一遍orders訂單數組--->常規操做--->獲得
    • table: 每一桌的桌號(key) ---> [每一桌上菜品的種類(key) ---> 及對應數量(value)] (value) 本質上就是map嵌套map
    • foods: 去重的菜品的種類
  3. res傳入標題 'Table'+ 排序後的foods (用擴展運算符...將set轉化爲數組)
  4. 遍歷table的每一桌,菜品存在,傳入數量,不然傳入0,注意到轉化爲str。 每次遍歷,將每一桌的桌號和下單的餐品數量依次傳入一個數組temp,再傳給res。
  5. 按餐桌桌號升序排列 sort(a,b)=>a[0]-b[0] (Unicode編碼上,數字比一切字母都小,能夠直接忽略res[0]標題)

代碼📃

// 1、hash法
let displayTable = (orders) => {
    let table = new Map(), foods = new Set(), res = []

    for(let [a, b, c] of orders){ //a:name b:table c: food ordered 
        foods.add(c)
        if(table.has(b)){
            let map = table.get(b)
            table.set(b, map.set(c, map.has(c) ? map.get(c)+1 : 1))
        }else{
            let map = new Map()
            table.set(b, map.set(c, 1))
        }
    }
    
    let menu = [...foods].sort()
    res.push(['Table',...menu])

    for(let [t, o] of table){ // t:tableId o: all ordered food in tableId
        let temp = []
        for(let n of menu){
            temp.push(o.has(n) ? '' + o.get(n) : '0')
        }
        res.push([t,...temp])
    }
    return res.sort((a,b)=>a[0]-b[0])
};
複製代碼

leetcode周賽185-3:🐸minNumberOfFrogs數青蛙

題目

給你一個字符串 croakOfFrogs,它表示不一樣青蛙發出的蛙鳴聲(字符串 "croak" )的組合。因爲同一時間能夠有多隻青蛙呱呱做響,因此 croakOfFrogs 中會混合多個 「croak」 。請你返回模擬字符串中全部蛙鳴所需不一樣青蛙的最少數目。

注意:要想發出蛙鳴 "croak",青蛙必須 依序 輸出 ‘c’, ’r’, ’o’, ’a’, ’k’ 這 5 個字母。若是沒有輸出所有五個字母,那麼它就不會發出聲音。

若是字符串 croakOfFrogs 不是由若干有效的 "croak" 字符混合而成,請返回 -1 。

具體題目及示例🌰

解題思路💡

1、計數法🐸

  1. 遍歷字符串,計數c r o a k ,若存在其餘字符返回-1
  2. 有效組合的條件爲c-->r-->o-->a-->k,不然返回-1
  3. 全部蛙鳴所需不一樣青蛙的最少數目cnt --->最多同時存在多少個c---> cnt = Math.max(cnt, c)
  4. 判斷k的值,若k==1,某隻青蛙的蛙鳴聲結束,c r o a k 均減1
  5. 遍歷結束後,如有多餘的c r o a k 返回-1

代碼📃

//1、計數法
let minNumberOfFrogs = (croakOfFrogs)=> {
    let c=0, r=0, o=0, a=0, k=0, cnt=0
    for(let x of croakOfFrogs){
        if(x=='c') c++
        else if(x=='r') r++
        else if(x == 'o') o ++
        else if(x == 'a') a ++
        else if(x == 'k') k ++
        else return -1
        if(r>c || o>r || a>o || k>a) return -1
        cnt = Math.max(c, cnt)
        if(k==1){
            c--
            r--
            o--
            a--
            k--
        }
    }
    return (c || r || o || a || k)? -1 : cnt
};
複製代碼

leetcode周賽185-4:🍨numOfArrays生成數組

題目

給你三個整數 n、m 和 k 。下圖描述的算法用於找出正整數數組中最大的元素。

img
img

請你生成一個具備下述屬性的數組 arr :

  • arr 中有 n 個整數。
  • 1 <= arr[i] <= m 其中 (0 <= i < n) 。
  • 將上面提到的算法應用於 arr ,search_cost 的值等於 k 。

返回上述條件下生成數組 arr 的 方法數 ,因爲答案可能會很大,因此 必須 對 10^9 + 7 取餘

具體題目及示例🌰

解題思路💡

1、三維dp🍨

dp狀態定義:dp[i][j][k]表示前i個元素,最大值爲j,同時search_cost爲k的方案數。

dp轉移方程:對於 1<= x <= m+1,存在兩種不一樣的狀況:

  1. j < x <= m 時, dp[i + 1][x][k + 1] += dp[i][j][k]

  2. 1 <= x <= j 時, dp[i + 1][j][k] += dp[i][j][k]

    (每次dp後應該對1e9+7 取餘)

空間複雜度:三維dp O(nmk)

時間複雜度:O(nmkm)

代碼📃

// 1、三維dp
let numOfArrays = (n, m, k)=> {
    let dp = new Array(n+1).fill(0).map(()=>new Array(m+1).fill(0).map(()=>new Array(k+1).fill(0)))
    let mod = 1e9+7, res = 0 
    dp[0][0][0] = 1
    for(let i = 0; i < n; i++)
        for(let j = 0; j <= m; j++)
            for(let k = 0; k <= i; k++)
                for(let x = 1; x <= m; x++){
                    if(x > j){
                        dp[i + 1][x][k + 1] += dp[i][j][k]
                        dp[i + 1][x][k + 1] %= mod
                    }
                    else {
                        dp[i + 1][j][k] += dp[i][j][k]
                        dp[i + 1][j][k] %= mod
                    }              
                }
    for(let i=1; i<=m; i++){
        res += dp[n][i][k]
        res %= mod
    }
    return res
};
複製代碼

本文使用 mdnice 排版

相關文章
相關標籤/搜索