動態規劃 最長公共子序列&最小編輯距離

https://leetcode-cn.com/problems/edit-distance/
https://leetcode-cn.com/problems/edit-distance/solution/zi-di-xiang-shang-he-zi-ding-xiang-xia-by-powcai-3/


最長公共子序列

描述

令 A = a1a2…an,B = b1b2…bn
令 L[ i , j ] 表示 a1a2…ai 和 b1b2…bj 的最長公共子序列的長度

當 A[i] == B[i],L[ i , j ] = L[ i-1 , j-1 ] + 1
當 A[i] != B[i],L[ i , j ] = max{ L[ i-1 , j ] , L[ i , j-1 ] }

eg:
A = horse,B = ros
i爲2,j爲2時,o == o,L[ ho , ro ] = L[ h , r ] + 1
i爲3,j爲3時,r != s,L[ hor , ros ] = max{ L[ ho , ros ] , L[ hor , ro ] }

例子

開始時,第一行、第一列均爲0
箭頭數值記錄來源(後續可根據箭頭方向恢復出最長公共子序列)

填完是這樣的

可以根據箭頭方向恢復出最長公共子序列(不唯一)

java實現

public static int LCS(String word1, String word2) {
	
    int[][] maxSub = new int[word1.length()+1][word2.length()+1];
    
	for(int i=1;i<word1.length()+1;i++) {
		for(int j=1;j<word2.length()+1;j++) {
			if(word1.charAt(i-1)==word2.charAt(j-1)) {
				maxSub[i][j] = maxSub[i-1][j-1] + 1;
			}else {
				maxSub[i][j] = Math.max(maxSub[i-1][j], maxSub[i][j-1]);
			}
		}
	}
    
	return maxSub[word1.length()][word2.length()];
}

最短編輯距離

描述

令 A = a1a2…an,B = b1b2…bn
令 L[ i , j ] 表示 a1a2…ai 和 b1b2…bj 的最短編輯距離

當 A[i] == B[i],L[ i , j ] = L[ i-1 , j-1 ]
當 A[i] != B[i],L[ i , j ] = min{ L[ i-1 , j-1 ] , L[ i-1 , j ] , L[ i , j-1 ] } + 1
其中,L[ i-1 , j-1 ] 代表替換操作,L[ i-1 , j ] 代表刪除操作,L[ i , j-1 ] 代表插入操作

eg:
A = horse,B = ros
i爲2,j爲2時,o == o,L[ ho , ro ] = L[ h , r ],無需繼續編輯
i爲3,j爲3時,r != s,L[ hor , ros ] = min{ L[ ho , ro ] , L[ ho , ros ] , L[ hor , ro ] } + 1
L[ ho , ro ] + 1 代表,在ho已經編輯成ro之後,將r替換成s
L[ ho , ros ] + 1 代表,在ho已經編輯成ros之後,將r刪除
L[ hor , ro ] + 1 代表,在hor已經編輯成ro之後,插入s

例子

開始時,第一行爲行序號,第一列爲列序號

填完是這樣的

編輯過程

java實現

public static int minDistance(String word1, String word2) {
	
    int[][] minEdit = new int[word1.length()+1][word2.length()+1];
    
    for(int i=1;i<word1.length()+1;i++) {
    	minEdit[i][0] = i;
    }
    for(int i=1;i<word2.length()+1;i++) {
    	minEdit[0][i] = i;
    }
    
	for(int i=1;i<word1.length()+1;i++) {
		for(int j=1;j<word2.length()+1;j++) {
			if(word1.charAt(i-1)==word2.charAt(j-1)) {
				minEdit[i][j] = minEdit[i-1][j-1];
			}else {
				int min = Math.min(minEdit[i-1][j], minEdit[i][j-1]);
				min = Math.min(min, minEdit[i-1][j-1]);
				minEdit[i][j] = min+1;
			}
		}
	}	
	
	return minEdit[word1.length()][word2.length()];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章