「西法帶你學算法」一次搞定前綴和

2020-10-01 腦洞前端

我花了幾天時間,從力扣中精選了五道相同思想的題目,來幫助大家解套,如果覺得文章對你有用,記得點讚分享,讓我看到你的認可,有動力繼續做下去。

  • 467. 環繞字符串中唯一的字符串[1](中等)
  • 795. 區間子數組個數[2](中等)
  • 904. 水果成籃[3](中等)
  • 992. K 個不同整數的子數組[4](困難)
  • 1109. 航班預訂統計[5](中等)

前四道題都是滑動窗口的子類型,我們知道滑動窗口適合在題目要求連續的情況下使用, 而前綴和[6]也是如此。二者在連續問題中,對於「優化時間複雜度」有著很重要的意義。 因此如果一道題你可以用暴力解決出來,而且題目恰好有連續的限制, 那麼滑動窗口和前綴和等技巧就應該被想到。

除了這幾道題, 還有很多題目都是類似的套路, 大家可以在學習過程中進行體會。今天我們就來一起學習一下。

前菜

我們從一個簡單的問題入手,識別一下這種題的基本形式和套路,為之後的四道題打基礎。當你了解了這個套路之後, 之後做這種題就可以直接套。

需要注意的是這四道題的前置知識都是 滑動窗口, 不熟悉的同學可以先看下我之前寫的 滑動窗口專題(思路 + 模板)[7]

母題 0

有 N 個的正整數放到數組 A 裡,現在要求一個新的數組 B,新數組的第 i 個數 B[i]是原數組 A 第 0 到第 i 個數的和。

這道題可以使用前綴和來解決。 前綴和是一種重要的預處理,能大大降低查詢的時間複雜度。我們可以簡單理解為「數列的前 n 項的和」。這個概念其實很容易理解,即一個數組中,第 n 位存儲的是數組前 n 個數字的和。

對 [1,2,3,4,5,6] 來說,其前綴和可以是 pre=[1,3,6,10,15,21]。我們可以使用公式 pre[]=pre[−1]+nums[]得到每一位前綴和的值,從而通過前綴和進行相應的計算和解題。其實前綴和的概念很簡單,但困難的是如何在題目中使用前綴和以及如何使用前綴和的關係來進行解題。

母題 1

如果讓你求一個數組的連續子數組總個數,你會如何求?其中連續指的是數組的索引連續。 比如 [1,3,4],其連續子數組有:[1], [3], [4], [1,3], [3,4] , [1,3,4],你需要返回 6。

一種思路是總的連續子數組個數等於:「以索引為 0 結尾的子數組個數 + 以索引為 1 結尾的子數組個數 + ... + 以索引為 n - 1 結尾的子數組個數」,這無疑是完備的。

同時「利用母題 0 的前綴和思路, 邊遍歷邊求和。」

參考代碼(JS):

function countSubArray(nums) {  let ans = 0;  let pre = 0;  for (_ in nums) {    pre += 1;    ans += pre;  }  return ans;}

「複雜度分析」

  • 時間複雜度:,其中 N 為數組長度。
  • 空間複雜度:

而由於以索引為 i 結尾的子數組個數就是 i + 1,因此這道題可以直接用等差數列求和公式 (1 + n) * n / 2,其中 n 數組長度。

母題 2

我繼續修改下題目, 如果讓你求一個數組相鄰差為 1 連續子數組的總個數呢?其實就是「索引差 1 的同時,值也差 1。」

和上面思路類似,無非就是增加差值的判斷。

參考代碼(JS):

function countSubArray(nums) {  let ans = 1;  let pre = 1;  for (let i = 1; i < nums.length; i++) {    if (nums[i] - nums[i - 1] == 1) {      pre += 1;    } else {      pre = 0;    }    ans += pre;  }  return ans;}

「複雜度分析」

  • 時間複雜度:,其中 N 為數組長度。
  • 空間複雜度:

如果我值差只要大於 1 就行呢?其實改下符號就行了,這不就是求上升子序列個數麼?這裡不再繼續贅述, 大家可以自己試試。

母題 3

我們繼續擴展。

如果我讓你求出不大於 k 的子數組的個數呢?不大於 k 指的是子數組的全部元素都不大於 k。 比如 [1,3,4] 子數組有 [1], [3], [4], [1,3], [3,4] , [1,3,4],不大於 3 的子數組有 [1], [3], [1,3] ,那麼 [1,3,4] 不大於 3 的子數組個數就是 3。 實現函數 atMostK(k, nums)。

參考代碼(JS):

function countSubArray(k, nums) {  let ans = 0;  let pre = 0;  for (let i = 0; i < nums.length; i++) {    if (nums[i] <= k) {      pre += 1;    } else {      pre = 0;    }    ans += pre;  }  return ans;}

「複雜度分析」

  • 時間複雜度:,其中 N 為數組長度。
  • 空間複雜度:

母題 4

如果我讓你求出子數組最大值剛好是 k 的子數組的個數呢? 比如 [1,3,4] 子數組有 [1], [3], [4], [1,3], [3,4] , [1,3,4],子數組最大值剛好是 3 的子數組有 [3], [1,3] ,那麼 [1,3,4] 子數組最大值剛好是 3 的子數組個數就是 2。實現函數 exactK(k, nums)。

實際上是 exactK 可以直接利用 atMostK,即 atMostK(k) - atMostK(k - 1),原因見下方母題 5 部分。

母題 5

如果我讓你求出子數組最大值剛好是 介於 k1 和 k2 的子數組的個數呢?實現函數 betweenK(k1, k2, nums)。

實際上是 betweenK 可以直接利用 atMostK,即 atMostK(k1, nums) - atMostK(k2 - 1, nums),其中 k1 > k2。前提是值是離散的, 比如上面我出的題都是整數。 因此我可以直接 減 1,因為 「1 是兩個整數最小的間隔」

如上,小於等於 10 的區域減去 小於 5 的區域就是 大於等於 5 且小於等於 10 的區域

注意我說的是小於 5, 不是小於等於 5。 由於整數是離散的,最小間隔是 1。因此小於 5 在這裡就等價於 小於等於 4。這就是 betweenK(k1, k2, nums) = atMostK(k1) - atMostK(k2 - 1) 的原因。

因此不難看出 exactK 其實就是 betweenK 的特殊形式。 當 k1 == k2 的時候, betweenK 等價於 exactK。

因此 atMostK 就是靈魂方法,一定要掌握,不明白建議多看幾遍。

有了上面的鋪墊, 我們來看下第一道題。

467. 環繞字符串中唯一的子字符串(中等)

題目描述

把字符串 s 看作是「abcdefghijklmnopqrstuvwxyz」的無限環繞字符串,所以 s 看起來是這樣的:"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". 現在我們有了另一個字符串 p 。你需要的是找出 s 中有多少個唯一的 p 的非空子串,尤其是當你的輸入是字符串 p ,你需要輸出字符串 s 中 p 的不同的非空子串的數目。 注意: p 僅由小寫的英文字母組成,p 的大小可能超過 10000。 示例 1:輸入: "a"輸出: 1解釋: 字符串 S 中只有一個"a"子字符。 示例 2:輸入: "cac"輸出: 2解釋: 字符串 S 中的字符串「cac」只有兩個子串「a」、「c」。. 示例 3:輸入: "zab"輸出: 6解釋: 在字符串 S 中有六個子串「z」、「a」、「b」、「za」、「ab」、「zab」。. 

前置知識

  • 滑動窗口

思路

題目是讓我們找 p 在 s 中出現的非空子串數目,而 s 是固定的一個無限循環字符串。由於 p 的數據範圍是 10^5 ,因此暴力找出所有子串就需要 10^10 次操作了,應該會超時。而且題目很多信息都沒用到,肯定不對。

仔細看下題目發現,這不就是母題 2 的變種麼?話不多說, 直接上代碼,看看有多像。

為了減少判斷, 我這裡用了一個黑科技, p 前面加了個 ^

class Solution:    def findSubstringInWraproundString(self, p: str) -> int:        p = '^' + p        w = 1        ans = 0        for i in range(1,len(p)):            if ord(p[i])-ord(p[i-1]) == 1 or ord(p[i])-ord(p[i-1]) == -25:                w += 1            else:                w = 1            ans += w        return ans

如上代碼是有問題。 比如 cac會被計算為 3,實際上應該是 2。根本原因在於 c 被錯誤地計算了兩次。因此一個簡單的思路就是用 set 記錄一下訪問過的子字符串即可。比如:

{    c,    abc,    ab,    abcd}

而由於 set 中的元素一定是連續的,因此上面的數據也可以用 hashmap 存:

{    c: 3    d: 4    b: 1}

含義是:

  • 以 b 結尾的子串最大長度為 1,也就是 b。
  • 以 c 結尾的子串最大長度為 3,也就是 abc。
  • 以 d 結尾的子串最大長度為 4,也就是 abcd。

至於 c ,是沒有必要存的。我們可以通過母題 2 的方式算出來。

具體算法:

  • 定義一個 len_mapper。key 是 字母, value 是 長度。 含義是以 key 結尾的最長連續子串的長度。

關鍵字是:最長

  • 用一個變量 w 記錄連續子串的長度,遍歷過程根據 w 的值更新 len_mapper
  • 返回 len_mapper 中所有 value 的和。

比如: abc,此時的 len_mapper 為:

{    c: 3    b: 2    a: 1}

再比如:abcab,此時的 len_mapper 依舊。

再比如: abcazabc,此時的 len_mapper:

{    c: 4    b: 3    a: 2    z: 1}

這就得到了去重的目的。這種算法是不重不漏的,因為最長的連續子串一定是包含了比它短的連續子串,這個思想和 1297. 子串的最大出現次數[8] 剪枝的方法有異曲同工之妙。

代碼(Python)

class Solution:    def findSubstringInWraproundString(self, p: str) -> int:        p = '^' + p        len_mapper = collections.defaultdict(lambda: 0)        w = 1        for i in range(1,len(p)):            if ord(p[i])-ord(p[i-1]) == 1 or ord(p[i])-ord(p[i-1]) == -25:                w += 1            else:                w = 1            len_mapper[p[i]] = max(len_mapper[p[i]], w)        return sum(len_mapper.values())

「複雜度分析」

  • 時間複雜度:,其中 為字符串 p 的長度。
  • 空間複雜度:由於最多存儲 26 個字母, 因此空間實際上是常數,故空間複雜度為 。

795. 區間數組個數(中等)

題目描述

給定一個元素都是正整數的數組 A ,正整數 L  以及  R (L <= R)。求連續、非空且其中最大元素滿足大於等於 L  小於等於 R 的子數組個數。例如 :輸入:A = [2, 1, 4, 3]L = 2R = 3輸出: 3解釋: 滿足條件的子數組: [2], [2, 1], [3].注意:L, R  和  A[i] 都是整數,範圍在  [0, 10^9]。數組  A  的長度範圍在[1, 50000]。

前置知識

  • 滑動窗口

思路

由母題 5,我們知道 「betweenK 可以直接利用 atMostK,即 atMostK(k1) - atMostK(k2 - 1),其中 k1 > k2」

由母題 2,我們知道如何求滿足一定條件(這裡是元素都小於等於 R)子數組的個數。

這兩個結合一下, 就可以解決。

代碼(Python)

代碼是不是很像

class Solution:    def numSubarrayBoundedMax(self, A: List[int], L: int, R: int) -> int:        def notGreater(R):            ans = cnt = 0            for a in A:                if a <= R: cnt += 1                else: cnt = 0                ans += cnt            return  ans        return notGreater(R) - notGreater(L - 1)

複雜度分析

  • 時間複雜度:,其中 為數組長度。
  • 空間複雜度:。

904. 水果成籃(中等)

題目描述

在一排樹中,第 i 棵樹產生 tree[i] 型的水果。你可以從你選擇的任何樹開始,然後重複執行以下步驟:把這棵樹上的水果放進你的籃子裡。如果你做不到,就停下來。移動到當前樹右側的下一棵樹。如果右邊沒有樹,就停下來。請注意,在選擇一顆樹後,你沒有任何選擇:你必須執行步驟 1,然後執行步驟 2,然後返回步驟 1,然後執行步驟 2,依此類推,直至停止。你有兩個籃子,每個籃子可以攜帶任何數量的水果,但你希望每個籃子只攜帶一種類型的水果。用這個程序你能收集的水果樹的最大總量是多少? 示例 1:輸入:[1,2,1]輸出:3解釋:我們可以收集 [1,2,1]。示例 2:輸入:[0,1,2,2]輸出:3解釋:我們可以收集 [1,2,2]如果我們從第一棵樹開始,我們將只能收集到 [0, 1]。示例 3:輸入:[1,2,3,2,2]輸出:4解釋:我們可以收集 [2,3,2,2]如果我們從第一棵樹開始,我們將只能收集到 [1, 2]。示例 4:輸入:[3,3,3,1,2,1,1,2,3,3,4]輸出:5解釋:我們可以收集 [1,2,1,1,2]如果我們從第一棵樹或第八棵樹開始,我們將只能收集到 4 棵水果樹。 提示:1 <= tree.length <= 400000 <= tree[i] < tree.length

前置知識

  • 滑動窗口

思路

題目花裡胡哨的。我們來抽象一下,就是給你一個數組, 讓你「選定一個子數組, 這個子數組最多只有兩種數字」,這個選定的子數組最大可以是多少。

這不就和母題 3 一樣麼?只不過 k 變成了固定值 2。另外由於題目要求整個窗口最多兩種數字,我們用哈希表存一下不就好了嗎?

set 是不行了的。 因此我們不但需要知道幾個數字在窗口, 我們還要知道每個數字出現的次數,這樣才可以使用滑動窗口優化時間複雜度。

代碼(Python)

class Solution:    def totalFruit(self, tree: List[int]) -> int:        def atMostK(k, nums):            i = ans = 0            win = defaultdict(lambda: 0)            for j in range(len(nums)):                if win[nums[j]] == 0: k -= 1                win[nums[j]] += 1                while k < 0:                    win[nums[i]] -= 1                    if win[nums[i]] == 0: k += 1                    i += 1                ans = max(ans, j - i + 1)            return ans        return atMostK(2, tree)

「複雜度分析」

  • 時間複雜度:,其中 為數組長度。
  • 空間複雜度:。

992. K 個不同整數的子數組(困難)

題目描述

給定一個正整數數組 A,如果 A 的某個子數組中不同整數的個數恰好為 K,則稱 A 的這個連續、不一定獨立的子數組為好子數組。(例如,[1,2,3,1,2] 中有 3 個不同的整數:1,2,以及 3。)返回 A 中好子數組的數目。 示例 1:輸入:A = [1,2,1,2,3], K = 2輸出:7解釋:恰好由 2 個不同整數組成的子數組:[1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2].示例 2:輸入:A = [1,2,1,3,4], K = 3輸出:3解釋:恰好由 3 個不同整數組成的子數組:[1,2,1,3], [2,1,3], [1,3,4]. 提示:1 <= A.length <= 200001 <= A[i] <= A.length1 <= K <= A.length

前置知識

  • 滑動窗口

思路

由母題 5,知:exactK = atMostK(k) - atMostK(k - 1), 因此答案便呼之欲出了。其他部分和上面的題目 904. 水果成籃 一樣。

實際上和所有的滑動窗口題目都差不多。

代碼(Python)

class Solution:    def subarraysWithKDistinct(self, A, K):        return self.atMostK(A, K) - self.atMostK(A, K - 1)    def atMostK(self, A, K):        counter = collections.Counter()        res = i = 0        for j in range(len(A)):            if counter[A[j]] == 0:                K -= 1            counter[A[j]] += 1            while K < 0:                counter[A[i]] -= 1                if counter[A[i]] == 0:                    K += 1                i += 1            res += j - i + 1        return res

「複雜度分析」

  • 時間複雜度:,中 為數組長度。
  • 空間複雜度:。

1109. 航班預訂統計(中等)

題目描述

這裡有  n  個航班,它們分別從 1 到 n 進行編號。我們這兒有一份航班預訂表,表中第  i  條預訂記錄  bookings[i] = [i, j, k]  意味著我們在從  i  到  j  的每個航班上預訂了 k 個座位。請你返回一個長度為 n 的數組  answer,按航班編號順序返回每個航班上預訂的座位數。示例:輸入:bookings = [[1,2,10],[2,3,20],[2,5,25]], n = 5輸出:[10,55,45,25,25]提示:1 <= bookings.length <= 200001 <= bookings[i][0] <= bookings[i][1] <= n <= 200001 <= bookings[i][2] <= 10000

前置知識

  • 前綴和

思路

這道題的題目描述不是很清楚。我簡單分析一下題目:

[i, j, k] 其實代表的是 第 i 站上來了 k 個人, 一直到 第 j 站都在飛機上,到第 j + 1 就不在飛機上了。所以第 i 站到第 j 站的「每一站」都會因此多 k 個人。

理解了題目只會不難寫出下面的代碼。

class Solution:    def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:        counter = [0] * n        for i, j, k in bookings:            while i <= j:                counter[i - 1] += k                i += 1        return counter

如上的代碼複雜度太高,無法通過全部的測試用例。

「注意到裡層的 while 循環是連續的數組全部加上一個數字,不難想到可以利用母題 0 的前綴和思路優化。」

一種思路就是在 i 的位置 + k, 然後利用前綴和的技巧給 i 到 n 的元素都加上 k。但是題目需要加的是一個區間, j + 1 及其之後的元素會被多加一個 k。一個簡單的技巧就是給 j + 1 的元素減去 k,這樣正負就可以抵消。

代碼(Python)

class Solution:    def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:        counter = [0] * (n + 1)        for i, j, k in bookings:            counter[i - 1] += k            if j < n: counter[j] -= k        for i in range(n + 1):            counter[i] += counter[i - 1]        return counter[:-1]

「複雜度分析」

  • 時間複雜度:,中 為數組長度。
  • 空間複雜度:。

總結

這幾道題都是滑動窗口和前綴和的思路。力扣類似的題目還真不少,大家只有多留心,就會發現這個套路。

前綴和的技巧以及滑動窗口的技巧都比較固定,且有模板可套。 難點就在於我怎麼才能想到可以用這個技巧呢?

我這裡總結了兩點:

  1. 找關鍵字。比如題目中有連續,就應該條件反射想到滑動窗口和前綴和。比如題目求最大最小就想到動態規劃和貪心等等。想到之後,就可以和題目信息對比快速排除錯誤的算法,找到可行解。這個思考的時間會隨著你的題感增加而降低。
  2. 先寫出暴力解,然後找暴力解的瓶頸, 根據瓶頸就很容易知道應該用什麼數據結構和算法去優化。

最後推薦幾道類似的題目, 供大家練習,一定要自己寫出來才行哦。

  • 303. 區域和檢索 - 數組不可變[9]
  • 1186.刪除一次得到子數組最大和[10]
  • 1310. 子數組異或查詢[11]
  • 1371. 每個元音包含偶數次的最長字符串[12]

大家對此有何看法,歡迎給我留言,我有時間都會一一查看回答。

更多算法套路可以訪問我的 LeetCode 題解倉庫:https://github.com/azl397985856/leetcode 。 目前已經 36K star 啦。

大家也可以關注我的公眾號《力扣加加》帶你啃下算法這塊硬骨頭。

Reference

[1]467. 環繞字符串中唯一的子字符串: https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/

[2]795. 區間子數組個數: https://leetcode-cn.com/problems/number-of-subarrays-with-bounded-maximum/

[3]904. 水果成籃: https://leetcode-cn.com/problems/fruit-into-baskets/

[4]992. K 個不同整數的子數組: https://leetcode-cn.com/problems/subarrays-with-k-different-integers/

[5]1109. 航班預訂統計: https://leetcode-cn.com/problems/corporate-flight-bookings/

[6]

前綴和: https://oi-wiki.org/basic/prefix-sum/

[7]滑動窗口專題(思路 + 模板): https://github.com/azl397985856/leetcode/blob/master/thinkings/slide-window.md

[8]1297. 子串的最大出現次數: https://github.com/azl397985856/leetcode/issues/266

[9]303. 區域和檢索 - 數組不可變: https://leetcode-cn.com/problems/range-sum-query-immutable/description/

[10]

1186.刪除一次得到子數組最大和: https://lucifer.ren/blog/2019/12/11/leetcode-1186/

[11]1310. 子數組異或查詢: https://lucifer.ren/blog/2020/01/09/1310.xor-queries-of-a-subarray/

[12]1371. 每個元音包含偶數次的最長子字符串: https://github.com/azl397985856/leetcode/blob/master/problems/1371.find-the-longest-substring-containing-vowels-in-even-counts.md

相關焦點

  • (一文學會字符串算法題目)
    所以建議「如果題目關鍵的部分直接用庫函數就可以解決,建議不要使用庫函數。」「如果庫函數僅僅是 解題過程中的一小部分,並且你已經很清楚這個庫函數的內部實現原理的話,可以考慮使用庫函數。」雙指針法 ,我們使用雙指針法實現了反轉字符串的操作,「雙指針法在數組,鍊表和字符串中很常用。」接著在 ,同樣還是使用雙指針法在時間複雜度O(n)的情況下完成替換空格。
  • 字節跳動的算法面試題是什麼難度?(第二彈)
    更多精彩內容,請期待我的搞定算法面試專欄。我是怎麼「保障不重不漏」的。實際上,這道題就是一個決策樹, 我畫個決策樹出來你就明白了。接下來,讓我們來「分析一下暴力為什麼低效,以及如何選取數據結構和算法能夠使得這個過程變得高效。」 記住這句話, 幾乎所有的優化都是基於這種思維產生的,除非你開啟了上帝模式,直接看了答案。 只不過等你熟悉了之後,這個思維過程會非常短, 以至於變成條件反射, 你感覺不到有這個過程, 這就是「有了題感。」
  • 「AI產品」如何讓Google的AI給你捕捉最美的自拍瞬間
    AI 老司機Google的相機部門非常喜歡搞一些黑科技,於是2017年就開發了一個自拍APP進行相關的探索,名為Selfissimo,究竟你的臉是仰角45度好呢還是側30度好,如果沒把握就交給AI去搞定吧。
  • 「暴躁」帶貨主播在線吵架,實屬大數據算法支配下的情非得已
    「我們貼了多少你知道麼?貼了兩千多萬!」 「賣了 9900 多萬,為了破億,貼!」 「不要再貼了!再貼要倒閉了!(破音)」
  • 關於回溯算法,你該了解這些
    「雖然回溯法很難,很不好理解,但是回溯法並不是什麼高效的算法」。「組合是不強調元素順序的,排列是強調元素順序」。例如:{1, 2} 和 {2, 1} 在組合上,就是一個集合,因為不強調順序,而要是排列的話,{1, 2} 和 {2, 1} 就是兩個集合了。
  • 騰訊面試題目「回溯算法」排列問題
    相信這個排列問題就算是讓你用for循環暴力把結果搜索出來,這個暴力也不是很好寫。所以正如我們在關於 所講的為什麼回溯法是暴力搜索,效率這麼低,還要用它?「因為一些問題能暴力搜出來就已經很不錯了!」,也就是說[1,2] 和[2,1] 是兩個集合,這和之前分析的子集以及組合所不同的地方」。
  • 細說英文單詞的前綴和後綴
    一、傳統定義中的前綴和後綴學英語的人一般都知道英文單詞有前綴和後綴,傳統的前綴、後綴是從詞性、詞義角度進行劃分的。先說後綴,一些詞加上後綴er、or變成名詞,表示從事某職業的人。還有加上前綴un表示反義,同樣帶un的單詞也有很多,卻沒有反義的意思,如uncle、under、undulate、unguent。第二個原因是,它只適合具有一定英語基礎和英語詞彙量的人,而且對基礎的要求還不低,至少要具有高中英語水平。為什麼這麼說呢?您想啊,如果不會讀write也不知道它是什麼意思,那怎麼能推出writer的意思呢?
  • 「元學習」解析:學習如何梯度下降與學習新的算法
    在這篇文章中,Cody 介紹了元學習的基本概念和方法類別,討論了「元學習」到底在學什麼、又有哪些限制。雷鋒網 AI 科技評論把全文編譯如下。具體來說,元學習的研究人員所追求的策略似乎可以分為兩類,它們大致可以和下面兩種人類認知「什麼是工具」的理論相對應。學到的先驗知識:從這一點看,人類可以很快地學習新的任務,因為我們可以重複使用我們已經在之前的任務中學到的信息。比如直覺上物體如何在空間中移動的物理特徵,或者在一個電子遊戲中死掉會降低獎勵的元知識。
  • 抖音小關老師帶貨「秘籍」:「人」與「貨」如何高效匹配
    在那段視頻的結尾,小關老師穿著廚師的白大褂,端著精細擺盤的牛排,對著鏡頭說:「煎牛排就跟小關老師學」。他的多數視頻以廚藝教學為主題,除了煎牛排,他還做過雙皮奶,可樂雞翅,視頻的點讚數都破了百萬。除了視頻創作受歡迎,小關老師在抖音上直播帶貨的成績也很亮眼。
  • 經典面試題目「回溯算法」解數獨
    一個數獨的解法需遵循如下規則:數字 1-9 在每一行只能出現一次。數字 1-9 在每一列只能出現一次。數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。空白格用 '.' 表示。
  • TikTok「魔力」推薦算法坐收一億用戶,不含算法的TikTok一文不值
    TikTok 使用的算法與國內抖音相互獨立,但比較難處理的是算法使用的內容和用戶信息。微軟前首席信息官 Jim Dubois 曾表示,「如果沒有數據,算法就一文不值。對這些國家數據進行分析是一項重要任務」。
  • 985相親局,TA們是如何利用「算法」挑選對象的?
    她馬上get到系統不會如自己設想般那樣「為人著想」。她的底線和標準,在系統一次次的行為記錄裡被下沉,但系統似乎並沒有盡力在幫自己找到那個「最優秀的人」。這與多數社交軟體註冊邀請頁面上所說的,「幫你在孤獨的世界找到另一個TA」,似乎並不一致。有一天,「TA說」上給林夕西推薦了一個哥倫比亞大學的碩士。
  • 零基礎學日語?這個小程序,帶你輕鬆入門「五十音」
    簡單地講,學習日語五十音就像學習漢語的拼音和英語的音標一樣,只有記住五十音的正確寫法和讀音,才能在日語學習的長路上打勝第一戰。可是之前如果不曾接觸過,就變得很難。今天,「知曉程序」推薦一款能帶你玩轉日語五十音的小程序——「五十音」,在日語學習的道路上助你一臂之力。據說,這款小程序的開發者,就是在開發的過程中掌握五十音的呢。它是有什麼超能力嗎?
  • 「機器學習」機器學習算法優缺點對比(匯總篇)
    然而,隨著你訓練集的增長,模型對於原數據的預測能力就越好,偏差就會降低,此時低偏差/高方差的分類器就會漸漸的表現其優勢(因為它們有較低的漸近誤差),而高偏差分類器這時已經不足以提供準確的模型了。「為什麼說樸素貝葉斯是高偏差低方差?」以下內容引自知乎:首先,假設你知道訓練集和測試集的關係。
  • 一張圖,搞定大數據工程師的成長路徑
    原標題:一張圖,搞定大數據工程師的成長路徑薪資高、機會多、缺口大,讓大數據在開發圈裡成了香餑餑。與此同時,在我做公眾號的這兩年,目睹了太多人「從入門到放棄」,甚至有些人連大數據的門都沒進來。看看你是那種?
  • 自然法師:「定業不可轉」和「萬法唯心」有矛盾嗎?
    你堅固執著就是抓著鏡色,抓著感覺,那叫定業。定是什麼?造作相,定業。你抓著那執著,已經抓著那鏡色,必受鏡色的迷惑,那能轉嗎?你抓著鏡色說:「我要轉鏡色」,就已然是迷惑了;你抓著感覺說:「我要轉感覺」,就已然是迷惑。你抓著那感覺就是什麼?
  • 985相親局:TA們是如何利用「算法」挑選對象的?
    她馬上get到系統不會如自己設想般那樣「為人著想」。她的底線和標準,在系統一次次的行為記錄裡被下沉,但系統似乎並沒有盡力在幫自己找到那個「最優秀的人」。這與多數社交軟體註冊邀請頁面上所說的,「幫你在孤獨的世界找到另一個TA」,似乎並不一致。有一天,「TA說」上給林夕西推薦了一個哥倫比亞大學的碩士。
  • 網際網路公司經典面試題目:「回溯算法」求組合問題
    「此時就會發現雖然想暴力搜索,但是用for循環嵌套連暴力都寫不出來!」咋整?回溯搜索法來了,雖然回溯法也是暴力,但至少能寫出來,不像for循環嵌套k層讓人絕望。那麼回溯法怎麼暴力搜呢?上面我們說了「要解決 n為100,k為50的情況,暴力寫法需要嵌套50層for循環,那麼回溯法就用遞歸來解決嵌套層數的問題」。
  • 2020「覺曉」帶你過法考!
    我們是全程帶著學,報班後你就什麼都不用管,跟著走就好。因為我們不是賣書、賣課的,我們會安排計劃、督促、測評、陪你一起努力。能帶的學生數量有限,你中途放棄,我們也覺得自己白白花了時間精力,會非常失落!中途放棄的不帶!
  • 用 Python 快速轉化「中文數字」和「阿拉伯數字」
    1 任務簡介這個任務的核心就是「中文數字」和「阿拉伯數字」相互轉化,這兩種數字的描述方式非常規則,比如 一百二十三 和 123。2.1 正向遍曆法首先,我們以 一百二十三 作為第一個要轉化的例子,你大概會說,這個用小學學過的知識就可以做到,的確如此!先把中文數字和單位做個映射,然後正向遍歷,用數字乘以單位,然後直接把他們累加起來就搞定了。