1. 程式人生 > >CS3K.com 九章算法基礎班

CS3K.com 九章算法基礎班

子串匹配 pre 一位 mov gif set 並且 原來 位數

Remove Substrings

技術分享圖片題目

思路:很容易想到貪心,能盡量削減原串就削減原串,但是貪心是錯誤的,反例:"abcabd", ["ab","abcd"]

   用DFS,對於dict中的每一個子串,在原串中找到匹配的該串的索引,並截取原字符串,更新結果,將截取後的字符串加入到隊列中(增加一個set來避免相同的串重復加入到隊列)以便下一次循環,然後從該索引後面的一個位置開始再找與該子串匹配的索引,重復上述過程。

技術分享圖片View Code

Permutation Index

技術分享圖片題目

思路:

對於某一個給定的位數A[i],需要判斷在它後面有幾個小於它的數,記下這個數字和A[i]所在的位置。

比如對於一個四位數,5316 , 第一位後面有2小於它的數,如果這兩個數排在第一位,那麽(1和3)各有3!的排列組合數小於(5316).

同理,對於第二位,其後有1個小於它的數,如果它放在第二位,那麽有2!種排列。

因此判斷一個給定數位於排列組合的第幾位,則可以按照以下公式進行

count1*(A.length-1)!+count2*(A.length-2)!+......+countn*(0)!

技術分享圖片View Code

Permutation Index II

技術分享圖片題目

思路:

這道題和Permutation IndexI思想一樣,計算每一位上數字是該位上第幾個排列,再將每一位結果加和即可。只是這道題有重復元素,有無重復元素最大的區別在於原來的1!, 2!, 3!...等需要除以重復元素個數的階乘。按照數字從低位到高位進行計算。每遇到一個重復的數字就更新重復元素個數的階乘的值。

  1. 從後往前遍歷數組,用一個hashmap來記錄重復元素個數。若新來的數不是重復元素,則加入hashmap,否則將重復元素個數+1,同時更新重復元素個數的階乘。

  2. 比較當前位和其後面位的數,計算當前位是第幾大的數count

  3. 當前位的index為:2的結果count * 其後面位數的階乘/重復數個數的階乘。將當前位計入階乘,重復1-3計算前一位。

  4. 註意:1.題目說index從1開始算。2.要用long來保存result,factor和repeatFactor,用int有可能超過範圍
技術分享圖片View Code

Maximum Subarray

技術分享圖片題目

思路:sum記錄到當前索引的子數組的和,minSum記錄該索引之前的子數組(從索引0開始)的和的最小值。sum - minSum表示以當前索引結尾的最大子數組的和,遍歷一遍後取sum - minSum的最大值即可。

技術分享圖片View Code

Maximum Subarray II

技術分享圖片題目

思路:求兩個不重疊的子數組的和最大。因為兩個subarray 一定不重疊,所以必定存在一條分割線,分開這兩個 subarrays。枚舉分割線的位置,left[] 和 right[] 裏分別存的是,某個位置往左的 maximum subarray 和往右的 maximum subarray。

技術分享圖片View Code

Maximum Subarray Difference

技術分享圖片題目

思路:求兩個不重疊的子數組的差的絕對值最大。與Maximum Subarray II的區別在於,需要求出left_max、left_min、right_max、right_min這四個數組,分別表示某個位置往左的最大子數組、某個位置往左的最小子數組、某個位置往右的最大子數組、某個位置往右的最小子數組。然後枚舉分割線的位置,對於某一位置的分割線,結果是左邊最大值與右邊最小值的差的絕對值或者左邊最小值與右邊最大值的差的絕對值。

技術分享圖片View Code

Maximum Subarray III

技術分享圖片題目

思路:

local[i][k]表示前i個元素取k個子數組並且必須包含第i個元素的最大和。

global[i][k]表示前i個元素取k個子數組不一定包含第i個元素的最大和。

local[i][k]的狀態函數:

max(global[i-1][k-1], local[i-1][k]) + nums[i-1]

有兩種情況,第一種是第i個元素自己組成一個子數組,則要在前i-1個元素中找k-1個子數組,第二種情況是第i個元素屬於前一個元素的子數組,因此要在i-1個元素中找k個子數組(並且必須包含第i-1個元素,這樣第i個元素才能合並到最後一個子數組中),取兩種情況裏面大的那個。

global[i][k]的狀態函數:

max(global[i-1][k],local[i][k])

有兩種情況,第一種是不包含第i個元素,所以要在前i-1個元素中找k個子數組,第二種情況為包含第i個元素,在i個元素中找k個子數組且必須包含第i個元素,取兩種情況裏面大的那個。

註意這一題中DP的方向是先從上往下,再從左往右,而不是通常的先從左往右,再從上往下。這樣做是因為localMax[j - 1][j]和globalMax[j - 1][j]置為Integer.MIN_VALUE的次數取決於列循環次數,而不是取決於行循環次數,否則二維數組下標會越界。

技術分享圖片View Code

Maximum Subarray IV

技術分享圖片題目

思路:同Maximum Subarray,區別在於更新min_pre的時機,不是每次循環都更新,而是i >= 的時候更新,這樣才能保證子數組長度大於等於k。

技術分享圖片View Code

Maximum Subarray V

技術分享圖片題目

思路:使用雙端隊列Deque,存放i,表示前i個數,第i個數到前index數之間的子數組有可能成為最大和子數組。每次循環,做三個操作:在列首踢掉長度大於k2的子數組的索引,在列尾踢掉子數組的和小於當前長度為k1的子數組的和,此時列首到當前索引的子數組為以當前元素為子數組的最後一個元素的長度在k1 ~ k2之間的最大和子數組,如果這個和比結果大就更新結果。

技術分享圖片View Code

LRU Cache

技術分享圖片題目

思路:HashMap + DoubleLinkedList  HashMap存儲key -> Node,Node節點裏的元素:1. key(可不要) 2. value 3. prev和next指針

這一道題的set操作如果set(key, value)的key已經存在的話,不算做最近使用的。

技術分享圖片View Code

LFU Cache

技術分享圖片題目

思路:雙HashMap + DoubleLinkedList。一個valueHash存儲:key -> value;另一個nodeHash存儲:key -> Node。

Node節點裏的元素:1. 頻率freq

          2. LinkedHashSet<Integer> keys存儲freq相同的key集合,可以保證先使用的Node放前面,最近使用的Node放後面

          3. prev和next指針

事先構造好虛擬的head和tail Node節點。

註意要隨時維護好valueHash、nodeHash和DoubleLinkedList中的元素關系。

技術分享圖片View Code

CS3K.com 九章算法基礎班