Time of Update: 2018-12-04
字典樹概念:字典樹,顧名思義,就是一種對字母等字串進行處理的一種特殊資料結構。說白了,就是二十六叉樹。定義一個頭指標,每次從頭指標開始操作。字典樹分析:對於統計詞頻方式,也可以採用hash一類方法,但採用字典樹更好,字典樹還可以對首碼進行統計,但在hash中無法實現。如果在極端情況下,每個節點下面都有26個字母,那麼佔用的空間為26^n,其中n表示單詞的平均長度。但對於單詞,很多節點是不可能出現,而有些節點是高頻出現,比如單詞的首碼 pre
Time of Update: 2018-12-04
問題:函數將字串中的字元'*'移到串的前部分,前面的非'*'字元後移,但不能改變非'*'分析:由於問題的特殊性,我們可以直接將字元往後移,那麼前面的位置全部用'*'填充,具體代碼如下:#include <iostream>#include <cstdio>using namespace std;/* * 這個方法將'*'往前移 */int change1(char *str){int i, j = strlen(str) - 1;for (i = j; j >= 0
Time of Update: 2018-12-04
問題:N*N的表格中存放自然數,從任意位置開始,表格中的數字可以向四鄰域移動(前提是移動方向上的數字必須小於當前數字),移動一次距離加一。求最大移動距離?分析:問題可以看成是一個動態規劃問題,H[i][j] = max{H[i-1][j], H[i+1][j], H[i][j-1], H[i][j+1]} + 1,其中滿足a[i][j] > a[i-1][j]等條件。經過和GJH討論,發現可以有更好的辦法,一次從矩陣中找到最小元素,更新最小元素周圍四個元素,更新結果為max{H[i][j]
Time of Update: 2018-12-04
問題:輸入一個字串,輸出該字串中對稱的子字串的最大長度。比如輸入字串“google”,由於該字串裡最長的對稱子字串是“goog”,因此輸出4。分析:暴力法,窮舉所有的子字串,然後判斷字串是否是對稱字串,如果是,則計算出長度和當前最長的字串比較,如果長度更長,更新結果。這種解法的時間複雜度為O(n^2)*O(n),前面的O(n^2)表示字串的總數數量級,後面的O(n)一個字串判斷是否對稱所花的時間。考慮使用另外的演算法,這也是參考《劍指offer》。每次選擇一次字元,往字元兩端進行擴充,擴充過程中
Time of Update: 2018-12-04
尋找字串中最長重複字串,方法:尾碼數組 + 快排代碼如下:/* * pp_15_2.cpp * * Created on: 2012-5-31 * Author: ict */#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>using namespace std;#define MAXN
Time of Update: 2018-12-04
問題的提出:給定n個整數(可能為負數)組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n 例如,當(a1,a2,a3,a4,a4,a6)=(-2,11,-4,13,-5,-2)時,最大子段和為20方法一:蠻力法方法二:分治法演算法描述如下: 針對最大子段和這個具體問題本身的結構,
Time of Update: 2018-12-04
題目:給定一個數組,比如5, 1, 2, 3, 4,求解該數組中逆序對的數目(這個數組包含4個逆序對,為5,1 5,2 5,3 5,4)分析:可以採用類似歸併排序方式,分而治之,將數組平分為兩部分,計算前後兩部分中存在的逆序對,在合并過程中,計算兩部分之間存在的逆序對數目代碼如下:/* * inverse_pair.cpp * * Created on: 2012-6-7 * Author: ict */#include <iostream>#include
Time of Update: 2018-12-04
給出兩個字串,通過三種操作:1,修改一個字元2,增加一個字元3,刪除一個字元一次操作,表示兩個字串的距離加1,通過三種操作,使得兩個字串最終相等,求解最少運算元,從而求得兩個字串的相似性,相似性表示為1/(距離 + 1)。比如abcdefg和abcdef距離為1(通過abcdefg刪除g一個操作),這樣相似性為1/2 =
Time of Update: 2018-12-04
前一段時間學了簡單的並查集,網上逛技術部落格,看到並查集的拓展,在原有並查集的基礎上,加入集合內部元素和其父節點之間的關係,這樣的拓展,可以解決更多問題題目連結:http://poj.org/problem?id=2492題目大意:輸入n個bug,bug之間有interaction,當前假設異性之間才interaction,但是需要驗證,給定這些interaction對,判定是否滿足假設如果男<->女和女<->男,滿足條件,如果存在男<->男或者女<-&
Time of Update: 2018-12-04
問題:在《編程珠璣》一書中,提到字串旋轉問題,比如有字串ab旋轉得到字串ba,那麼可以通過(a'b')'得到,其中“ '
Time of Update: 2018-12-04
解法三中,採用兩個棧的方式建立一個隊列,其中stack支援的方法有:1,pop()2,push()3,max()其中在push()和pop()過程中需要動態修改最大值,其中採用link2NextMaxItem[]數組儲存當前元素的上一級最大元素,這裡需要理解其中的原理,為什麼這樣可以?其中必須理解stack的特性,先進後出的性質,這樣書上的操作是正確的,每次進來的數值,只和已經進棧的最大值比較,並且記錄舊的最大值位置,而不用記錄後面入棧的數值。
Time of Update: 2018-12-04
題目:在一個盒子裡面有N根繩子,這個N根繩子的中間部分放在盒子裡面,不可見,但是這個N根繩子的兩端露在盒子外面,所以我們能看到2N個繩頭。 隨機選取2個繩頭並打結,直到所有的繩頭都打上結。最後這些打結的繩子會形成許多環。請問環數目的期望值是多少?分析:以下內容直接從另外的部落格轉載的:--------------------------------------------------這個題目可以通過歸納法來看:假設繩子個數為n時,環的期望為E(n)n=1 E(1) =
Time of Update: 2018-12-04
題目:微軟電面問到的問題,前面提了一大堆背景,最後歸結為一個問題,如何在連續的網路流量中,等機率隨機抽取1個資料包。分析:參加電面時,還沒看過蓄水池抽樣問題,後來回來一搜,這就是典型的蓄水池抽樣問題,不過當時自己也想到了一種解法,使用一個變數儲存資料包,從1到i個資料包,每次遇到第i個資料包,以1/i的機率選取這個資料包,並且替換原來的資料包,這樣到第n個資料包,我們能保證我們以1/n的機率選取這n個資料包中的1個。證明:加入第i個資料包到來,我們以1/i的機率選取這個資料包,顯然,它的機率是符
Time of Update: 2018-12-04
題目:一個unit cubic,一隻螞蟻在一個角,準備在這個cubic的edge上開始爬動。螞蟻爬過一條邊的時間為1,它在任意一個角的時候,往其他三個方向去的機率都是1/3.問螞蟻從一個角爬到對角的平均時間是多少?分析:直接轉載的:---------------------------------------一個unit
Time of Update: 2018-12-04
題目:一棵二叉尋找樹,得到一個後序遍曆,判斷這個後序遍曆是否正確。分析:方法1,根據中序和後序根據中序和後序,可以唯一得到一棵二叉樹。一棵二叉尋找樹的中序顯然就是所有數位正常排序,所以,我們首先將所有的後序得到的數字排序,時間複雜度是O(nlogn),然後根據後序和中序遍曆,判斷二叉樹是否可以建立。總的時間複雜度就是O(nlogn)。方法2,直接利用尋找二叉樹的性質顯然,後序遍曆的最後一個數字是根節點,然後根據尋找二叉樹的性質,我們將前面的數字分為兩部分,前面一部分都是小於根節點的數字,後面的數
Time of Update: 2018-12-04
編程珠璣單詞中,需要統計《聖經》一書中,出現頻率最高的單詞,這是典型的TOP K問題,採用經典的Hash + 堆方法解決,代碼如下:#include <stdio.h>#include <string.h>#include <malloc.h>#include <assert.h>#include <stdlib.h>#include <ctime>#define HASHLEN 101#define WORDLEN 30#
Time of Update: 2018-12-04
問題:給定一個二維數組,這個二維數組的每行、每列數字都是遞增的,尋找某個整數是否在二維數組內。分析:這題和堆排序有類似,尋找過程中從右上方的數字開始,如果該數字比尋找的數字小,那麼該數字所在行可以刪除,不用繼續考慮;如果該數字比尋找的數字大,那麼該數字所在列可以刪除。這樣,每次執行,都會刪除一行或者一列,極端情況下,執行2n次。演算法代碼:#include <iostream>#include <cstdlib>#include <cstdio>using
Time of Update: 2018-12-04
問題:兩個有序數組,合并成一個有序數組,假設第一個數組空間足夠容納兩個數組。分析:考慮到a數組很大,可以直接在a數組上進行合并,但是要講究效率。如果單純從前往後合并,那麼效率會非常低,因為a數組後面的數字需要不停的移動。換一種思路,我們採用從後往前合并,首先計算出總長度,設定一個指標從a數組最後往前移動。演算法代碼:#include <iostream>#include <cstdio>#include <cstdlib>using namespace
Time of Update: 2018-12-04
POJ:http://poj.org/problem?id=2528這兩天在學習線段樹演算法,參考了網上許多線段樹的資料,用Google搜一下,就能搜到很多,這裡就不詳細解釋什麼事線段樹了。線段樹在解決區間重合問題,比如求一段區間,最大值,最小值,求和等問題非常有效,一次查詢的時間複雜度是log(n),時間複雜度非常理想。題目大意:在牆壁上貼廣告,廣告的版面有大有小,並且貼廣告有先後之分,後面貼的廣告會覆蓋前面的廣告,求解最後能看到的廣告面,如所示:兩種視圖,最後從From
Time of Update: 2018-12-04
ADD: http://blog.chinaunix.net/u3/102827/showart_2045521.html Normal 0 7.8 磅 0 2 false false false MicrosoftInternetExplorer4 classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui>st1