つの文字列の削除操作
22189 ワード
これは一連のleetcode解決説明の一部です.あなたがこの解決が好きであるか、それが役に立つとわかるならば、このポストとmy solution post on Leetcode's forums .
Leetcode Problem #583 (Medium): Delete Operation for Two Strings
説明
にジャンプします.Solution Idea || コードJavaScript | Python | Java | C++ )
例:
制約
考え
にジャンプします.Problem Description || コードJavaScript | Python | Java | C++ )
この問題は基本的に2つの単語(W 1、W 2)の間で最も長い共通部分系列(LCS)を特定するように私たちに頼みます.答えは、単語の長さとLCSの長さの間の組み合わせの違いになります.
典型的なLCS解決のために、我々はボトムアップ動的プログラミング(DP)アプローチを使用して、互いに対して各々の単語の各々の手紙を比較するために入れ子状のループを使用します(w 1 [ i ]、w 2 [ j ]).これは通常、M = W 1のサイズ( M + 1 )*( n + 1 )のDP配列を呼び出します.長さとn = w 2.長さ.LCSプロセスは、ターゲットセルの前の行と列を参照しているので、0でいっぱいのセルの余分なバッファが必要になります.DP [ i ][ j ]でDP配列の各セルは、W 1の間で見つけられる最も長いサブシーケンスを表します.substr ( 0 , i )とW 2susbtr ( 0 , j )最終的な答えはDP [ M ] [ N ]です.
DP配列が反復的に構築されているので、順番に、現在の行と最後の行(dpcurr、dplast)を繰り返すだけでO(n * m)から正常な空間の複雑さを減らすことができます.これはo ( n )にスペースの複雑さを落とすでしょう.これを行うには、必要に応じて短い単語が2つの単語をスワップすることによってNに使用されることも保証できます. 時間の複雑さ:n(n)とmは2つの単語の長さである 空間の複雑さ:O(n)は、Nが2つの語のより小さい長さです
実装
JavaScriptとJavaでは、文字列ではなく配列を繰り返し実行することが容易になりますので、最初にsplit ()またはtochararray ()という2つの単語( WA 1 , WA 2 )を指定できます.
JavaScriptコード
にジャンプします.Problem Description || Solution Idea )
Pythonコード:
にジャンプします.Problem Description || Solution Idea )
Javaコード:
にジャンプします.Problem Description || Solution Idea )
C++コード:
にジャンプします.Problem Description || Solution Idea )
Leetcode Problem #583 (Medium): Delete Operation for Two Strings
説明
にジャンプします.Solution Idea || コードJavaScript | Python | Java | C++ )
Given two strings
word1
andword2
, return the minimum number of steps required to makeword1
andword2
the same.In one step, you can delete exactly one character in either string.
例:
Example 1: Input: word1 = "sea", word2 = "eat" Output: 2 Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".
Example 2: Input: word1 = "leetcode", word2 = "etco" Output: 4
制約
1 <= word1.length, word2.length <= 500
word1
andword2
consist of only lowercase English letters.
考え
にジャンプします.Problem Description || コードJavaScript | Python | Java | C++ )
この問題は基本的に2つの単語(W 1、W 2)の間で最も長い共通部分系列(LCS)を特定するように私たちに頼みます.答えは、単語の長さとLCSの長さの間の組み合わせの違いになります.
典型的なLCS解決のために、我々はボトムアップ動的プログラミング(DP)アプローチを使用して、互いに対して各々の単語の各々の手紙を比較するために入れ子状のループを使用します(w 1 [ i ]、w 2 [ j ]).これは通常、M = W 1のサイズ( M + 1 )*( n + 1 )のDP配列を呼び出します.長さとn = w 2.長さ.LCSプロセスは、ターゲットセルの前の行と列を参照しているので、0でいっぱいのセルの余分なバッファが必要になります.DP [ i ][ j ]でDP配列の各セルは、W 1の間で見つけられる最も長いサブシーケンスを表します.substr ( 0 , i )とW 2susbtr ( 0 , j )最終的な答えはDP [ M ] [ N ]です.
DP配列が反復的に構築されているので、順番に、現在の行と最後の行(dpcurr、dplast)を繰り返すだけでO(n * m)から正常な空間の複雑さを減らすことができます.これはo ( n )にスペースの複雑さを落とすでしょう.これを行うには、必要に応じて短い単語が2つの単語をスワップすることによってNに使用されることも保証できます.
実装
JavaScriptとJavaでは、文字列ではなく配列を繰り返し実行することが容易になりますので、最初にsplit ()またはtochararray ()という2つの単語( WA 1 , WA 2 )を指定できます.
JavaScriptコード
にジャンプします.Problem Description || Solution Idea )
var minDistance = function(W1, W2) {
let m = W1.length, n = W2.length
if (m < n) [W1, W2, m, n] = [W2, W1, n, m]
let WA1 = W1.split(""), WA2 = W2.split(""),
dpLast = new Uint16Array(n + 1),
dpCurr = new Uint16Array(n + 1)
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++)
dpCurr[j+1] = WA1[i] === WA2[j]
? dpLast[j] + 1
: Math.max(dpCurr[j], dpLast[j+1]);
[dpLast, dpCurr] = [dpCurr, dpLast]
}
return m + n - 2 * dpLast[n]
};
Pythonコード:
にジャンプします.Problem Description || Solution Idea )
class Solution:
def minDistance(self, W1: str, W2: str) -> int:
m, n = len(W1), len(W2)
if m < n: W1, W2, m, n = W2, W1, n, m
dpLast, dpCurr = [0] * (n + 1), [0] * (n + 1)
for c1 in W1:
for j in range(n):
dpCurr[j+1] = dpLast[j] + 1 if c1 == W2[j] else max(dpCurr[j], dpLast[j+1])
dpLast, dpCurr = dpCurr, dpLast
return m + n - 2 * dpLast[n]
Javaコード:
にジャンプします.Problem Description || Solution Idea )
class Solution {
public int minDistance(String W1, String W2) {
int m = W1.length(), n = W2.length();
if (m < n) {
String tempStr = W1;
W1 = W2;
W2 = tempStr;
int tempInt = n;
n = m;
m = tempInt;
}
char[] WA1 = W1.toCharArray(), WA2 = W2.toCharArray();
int[] dpLast = new int[n+1], dpCurr = new int[n+1];
for (char c1 : WA1) {
for (int j = 0; j < n; j++)
dpCurr[j+1] = c1 == WA2[j]
? dpLast[j] + 1
: Math.max(dpCurr[j], dpLast[j+1]);
int[] tempArr = dpLast;
dpLast = dpCurr;
dpCurr = tempArr;
}
return m + n - 2 * dpLast[n];
}
}
C++コード:
にジャンプします.Problem Description || Solution Idea )
class Solution {
public:
int minDistance(string W1, string W2) {
int m = W1.size(), n = W2.size();
if (m < n) swap(W1, W2), swap(n, m);
vector<int> dpLast(n+1, 0), dpCurr(n+1, 0);
for (char c1 : W1) {
for (int j = 0; j < n; j++)
dpCurr[j+1] = c1 == W2[j]
? dpLast[j] + 1
: max(dpCurr[j], dpLast[j+1]);
swap(dpLast, dpCurr);
}
return m + n - 2 * dpLast[n];
}
};
Reference
この問題について(つの文字列の削除操作), 我々は、より多くの情報をここで見つけました https://dev.to/seanpgallivan/solution-delete-operation-for-two-strings-235kテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol