2、給定乙個query和乙個text,均由小寫字母組成。要求在text中找出以同樣的順序連續出現在query中的最長連續字母序列的長度。例如, query為「acbac」,text為「acaccbabb」,那麼text中的「cba」為最長的連續出現在query中的字母序列,因此,返回結果應該為其長度3。請注意程式效率。
解析:此題其實就是求公共最長(連續)子串的問題。
最簡單的方法就是依次比較,以某個串為母串,然後生成另乙個串的所有長度的子串,依次去母串中比較查詢,這裡可以採用先從最長的子串開始,減少比較次數,但是複雜度依然很高!
然後重新看一下這個問題,我們建立乙個比較矩陣來比較兩個字串str1和str2
定義 lcs(i,j) ,當str1[i] = str2[j]時lcs(i,j)=1,否則等於0。
example:
str1 = "bab"
str2 = "caba"
建立矩陣
--b a b
c 0 0 0
a 0 1 0
b 1 0 1
a 0 1 0
連續i子串的特點就是如果str1[i]和str2[j]是屬於某公共子串的最後乙個字元,那麼一定有str1[i]=str2[j] && str1[i-1] = str2[j-1],從矩陣中直觀的看,就是由「1」構成的「斜線」代表的序列都是公共子串,那麼最長公共子串肯定就是斜線「1」最長的那個串。
那麼現在問題就可以轉化了,只要構造出如上的乙個矩陣,用n^2的時間就可以得到矩陣,然後再到矩陣中去尋找最長的那個「1」構成的斜線就可以了!那麼,現在又有了新的問題?如何快速的找到那個「1」構成的最長斜線呢?
採用dp的思想,如果str1[i] = str2[j],那麼此處的包含str1[i] 和 str2[j]公共子串的長度必然是包含str1[i-1]和str2[j-1]的公共子串的長度加1,那麼現在我們可以重新定義lcs(i,j),即是lcs(i,j) = lcs(i-1,j-1) + 1,反之,lcs(i,j) = 0。那麼上面的矩陣就變成了如下的樣子:
--b a b
c 0 0 0
a 0 1 0
b 1 0 2
a 0 2 0
現在問題又變簡單了,只需要花n^2的時間構造這樣乙個矩陣,再花n^2的時間去找到矩陣中最大的那個值,對應的就是最長公共子串的長度,而最大值對應的位置對應的字元,就是最長公共子串的最末字元。
演算法還可以改進,我們可以將查詢最大長度和對應字元的工作放在構造矩陣的過程中完成,一邊構造一邊記錄當前的最大長度和對應位置,這樣就節省了n^2的查詢時間。
空間上也可以做改進,如果按照如上的方式構造,我們發現,當矩陣的第i+1行的值計算完成後,第i行的值就沒有用了,即便是最長的長度出現在第i行,我們也已經用變數記錄下來了。因此,可以將矩陣縮減成乙個向量來處理,向量的當前值對應第i行,向量的下乙個迴圈後的值對應第i+1行。
下面是我寫的**:
#include #include using namespace std;
// 查詢公共子串
// lcs記錄公共子串
// return 公共子串長度
int lcs(const char *str1 , const char *str2 , char *lcs)
int len1=strlen(str1);
int len2=strlen(str2);
int *m=new int[len1];
int maxlen=0;
int endpos;
for(int i=0;i=0;j--)
else
}else
m[j]=0;
if(maxlen
2023年阿里巴巴校招筆試題
校招找工作的同學,可以看看,非常有幫助!推薦 產品經理 阿里巴巴2015校園招聘筆試題 研發工程師 阿里巴巴2015校園招聘筆試題 研發工程師 阿里巴巴2015校園招聘筆試題2 國際安全運營專員 阿里巴巴2015校園招聘筆試題1 產品運營 阿里巴巴2015校園招聘筆試題1 前端開發工程師 阿里巴巴2...
阿里巴巴 2018秋招研發工程師筆試題
2.菜鳥倉庫是乙個很大很神奇的地方,各種琳琅滿目的商品整整齊齊地擺放在一排排貨架上,通常一種品類 sku 的商品會放置在貨架的某乙個格仔中,格仔設有統一的編號,方便工人們揀選。有一天沐哲去菜鳥倉庫參觀,無意中發現第1個貨架格仔編碼為1,第2 3個分別為1,2,第4 6個格仔分別是1,2,3,第7 1...
阿里巴巴研發C 筆試
答選擇題只有乙個感受,數學不好抱憾終生 選擇題差不多三分之一是數學方面,概率,排列組合之類的題目,三分之一的c 基礎知識,三分之一的資料結構和演算法,比如紅黑樹 二叉樹。簡答題有三道。感覺都是比較實際的問題 freelist 第一道題大概是為了避免頻繁的new delete操作,實現乙個freeli...