JavaScript 查找形成回文的最小插入次数
给定一个字符串,我们需要找到最小的插入次数,将不同的字符插入给定的字符串的任何位置,使得最终的字符串成为回文。回文是一个与其反转相等的字符串。这个问题是动态规划的问题,所以我们首先使用递归方法解决,然后将其记忆化,最后再看一下记忆化方法的表格化。
递归方法
示例
const max = 1e5; // defining the upper limit
// function to find the minimum of two number as it is not present in the c language
function findMin(a, b){
if(a < b){
return a;
} else{
return b;
}
}
// creating the function for finding the required answer we will make recursive calls to it
function findAns(str,start,end){
// base condition
if (start > end){
return max;
}
else if(start == end){
return 0;
}
else if (start == end - 1){
if(str[start] == str[end]){
return 0;
}
else return 1;
}
// check if both start and end characters are the same make calls on the basis of that
if(str[start] == str[end]){
return findAns(str,start+1, end-1);
} else{
return 1+ findMin(findAns(str,start,end-1), findAns(str,start+1,end));
}
}
// given inputs
var str = "thisisthestring"; // given string
console.log("The minimum number of insertions required to form the palindrome is: " + findAns(str,0,str.length-1));
输出
The minimum number of insertions required to form the palindrome is: 8
时间和空间复杂度
以上代码的时间复杂度为O(2^N),因为我们对每个插入都做出了选择,其中N是给定字符串的大小。
以上代码的空间复杂度为O(N),用于递归调用。
记忆化方法
示例
const max = 1e5; // defining the upper limit
var memo = new Array(1005); // array to store the recursion results
// function to find the minimum of two number as it is not present in the c language
function findMin(a, b){
if(a < b){
return a;
} else{
return b;
}
}
// creating function for finding the required answer we will make recursive calls to it
function findAns(str,start,end){
// base condition
if (start > end){
return max;
}
else if(start == end){
return 0;
}
else if (start == end - 1){
if(str[start] == str[end]){
return 0;
}
else return 1;
}
if(memo[start][end] != -1){
return memo[start][end];
}
// check if both start and end characters are the same make calls on the basis of that
if(str[start] == str[end]){
memo[start][end] = findAns(str,start+1, end-1);
} else{
memo[start][end] = 1+ findMin(findAns(str,start,end-1), findAns(str,start+1,end));
}
return memo[start][end];
}
// given inputs
var str = "thisisthestring"; // given string
// initialzie the memo array
for(var i=0; i< 1005; i++){
memo[i] = new Array(1005);
for(var j = 0; j<1005; j++){
memo[i][j] = -1;
}
}
console.log("The minimum number of insertions required to form the palindrome is: " + findAns(str,0,str.length-1));
输出
The minimum number of insertions required to form the palindrome is: 8
时间和空间复杂度
上述代码的时间复杂度是O(N^2),因为我们存储了已经计算的结果。
上述代码的空间复杂度是O(N^2),因为我们在这里使用了额外的空间。
动态规划方法
示例
const max = 1e5; // defining the upper limit
var memo = new Array(1005); // array to store the recursion results
// function to find the minimum of two number as it is not present in the c language
function findMin(a, b){
if(a < b){
return a;
} else{
return b;
}
}
// creating a function for finding the required answer we will make recursive calls to it
function findAns(str, len){
// filling the table by traversing over the string
for (var i = 1; i < len; i++){
for (var start= 0, end = i; end < len; start++, end++){
if(str[start] == str[end]){
memo[start][end] = memo[start+1][end-1];
} else{
memo[start][end] = 1 + findMin(memo[start][end-1], memo[start+1][end]);
}
}
}
// return the minimum numbers of interstion required for the complete string
return memo[0][len-1];
}
// given inputs
var str = "thisisthestring"; // given string
// initialzie the memo array
for(var i=0; i< 1005; i++){
memo[i] = new Array(1005);
for(var j = 0; j<1005; j++){
memo[i][j] = 0;
}
}
console.log("The minimum number of insertions required to form the palindrome is: " + findAns(str,str.length));
输出结果
The minimum number of insertions required to form the palindrome is: 8
时间和空间复杂度
上面代码的时间复杂度是O(N^2),因为我们在这里使用了嵌套的for循环。
上面代码的空间复杂度是O(N^2),因为我们在这里使用了额外的空间。
结论
在本教程中,我们使用JavaScript编程语言实现了从递归到记忆化再到表格化的三种方法,来找到使给定字符串成为回文所需的最小插入次数。回文是一个字符串,它与其反向相等,或者可以从前或者从后读取的字符是相同的。