【經典面試題一】最長公共子序列(經典動態規劃題)

1.問題描述:

  什麼是最長公共子序列呢?比如一個數列 S,若是分別是兩個或多個已知數列的子序列,且是全部符合此條件序列中最長的,則S 稱爲已知序列的最長公共子序列。html

  舉個例子,如:有兩條隨機序列,如 1 3 4 5 5 ,and 2 4 5 5 7 6,則它們的最長公共子序列即是:4 5 5。ios

  

  注意:【最長公共子串(Longest CommonSubstring)和最長公共子序列(LongestCommon Subsequence, LCS)的區別】算法

  子串(Substring)是串的一個連續的部分,子序列(Subsequence)則是從不改變序列的順序,而從序列中去掉任意的元素 而得到的新序列;更簡略地說,前者(子串)的字符的位置必須連續,後者(子序列LCS)則沒必要。好比字符串acdfg同akdfc的最長公共子串爲df, 而他們的最長公共子序列是adf。LCS可使用動態規劃法解決。下文具體描述。優化

2.解決思路:

2.1窮舉法

  (靠蠻力啊。。。)spa

2.2動態規劃法

  用動態規劃法首先要判斷該問題是否符合動態規劃法的條件。時間複雜度O(n^2)。code

  (1) 最優化原理:若是問題的最優解所包含的子問題的解也是最優的,就稱該問題具備最優子結構,即知足最優化原理。htm

  (2) 無後效性:即某階段狀態一旦肯定,就不受這個狀態之後決策的影響。也就是說,某狀態之後的過程不會影響之前的狀態,只與當前狀態有關。blog

  (3) 有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被屢次使用到。(該性質並非動態規劃適用的必要條件,可是若是沒有這條性質,動態規劃算法同其餘算法相比就不具有優點)字符串

3.源碼:

// LCSTest.cpp : 定義控制檯應用程序的入口點。  
#include "stdafx.h"  
#include<iostream>  
#include<cstdlib>  
#include<string>  
#include<vector>  
using namespace std;  
      
void LCS(string str1,string str2)  
{  
    int len1 = str1.length();  
    int len2 = str2.length();  
    //int **dp = new int[len1+1][len2+1];  
    vector<vector<int> > dp(len1+1,vector<int>(len2+1));  
          
    //動態規劃初始值     
    for(int j = 0;j <= len2;j++)  
        dp[0][j] = 0;  
    for(int i = 0;i <=len1;i++)  
        dp[i][0] = 0;  
    
    for(int i = 0;i < len1;i++)  
        for(int j = 0;j < len2;j++)  
        {  
            if(str1.at(i) == str2.at(j))  
            {  
                dp[i+1][j+1]= dp[i][j]+1;                 
            }  
            else if(dp[i][j+1] > dp[i+1][j])  
                dp[i+1][j+1] = dp[i][j+1];  
            else   
                dp[i+1][j+1] = dp[i+1][j];  
        }  
        cout<<"最長公共子序列長度爲:"<<dp[len1][len2]<<endl;  
      
        int ti = 0;  
        int tj = 0;  
        while(ti<len1 && tj<len2 )  
        {  
            if(str1.at(ti) == str2.at(tj))  
            {  
                cout<<str1.at(ti)<<" ";  
                ti++;  
                tj++;  
            }  
            else if(dp[ti+1][tj] >= dp[ti][tj+1])  
                ti++;  
            else  
                tj++;  
        }  
}  
int _tmain(int argc, _TCHAR* argv[])  
{  
    string str1 = "asddgflsksdjflkdf";  
    string str2 = "sdflsdzf";  
    LCS(str1,str2);  
    return 0;  
}  
相關文章
相關標籤/搜索