C++ 从给定数组中选择字符串并满足条件后的最大字符串长度

C++ 从给定数组中选择字符串并满足条件后的最大字符串长度

在这个问题中,我们需要通过将数组字符串追加到一个字符串中,找到最大的结果字符串的长度。这样,如果我们选择了一个长度为x的字符串,我们可以选择接下来的x/2个字符串。

我们可以使用递归函数、记忆化和动态规划方法来解决这个问题。

问题陈述-我们有一个名为str_array的字符串数组,其中包含N个字符串。我们需要将数组中给定的字符串添加到结果字符串中,并找到结果字符串的最大长度。在将字符串追加到结果字符串时,我们需要遵循以下规则:如果我们选择任何长度为x的字符串,那么我们不能选择数组中的接下来的x/2个字符串。

示例样例

输入

str_array[] = {"tutor", "po", "nt", "welco", "ghj"}

输出

10

解释 - 我们可以选择“tutor”和“welco”字符串。

输入

str_array[] = {"tu", "po", "nt", "wel", "ghj"}

输出

7

说明 - 我们可以选择“tu”、“nt”和“ghj”字符串。结果字符串的长度将为7。

输入

str_array[] = {"tutorialspoint", "po", "nt", "wel", "ghj"};

输出

14

解释 - 我们只能选择“tutorialspoint”字符串。

为了解决这个问题,我们需要对字符串进行2N次选择,并根据选择的最大长度选择最终答案。

方法1

在这个方法中,我们将创建一个递归函数来考虑字符串的所有选择,并根据所有选择选择最大长度。

算法

步骤1 - 首先,定义基本情况。如果数组长度小于start,返回0。

步骤2 - 现在,我们必须对当前字符串进行选择。第一种选择是包含字符串。如果我们包含字符串,将字符串大小添加到递归函数的返回值中。同时,改变start参数的值,因为我们无法选择下一个x/2的长度,其中x是字符串长度。

步骤3 - 如果我们不包含当前字符串,在增加start参数值1之后,进行递归函数调用。

步骤4 - 从sol1和sol2中选择最大值并返回。

示例

#include <bits/stdc++.h>
using namespace std;

int maxStringSize(string str_array[], int len, int start) {
   // Return 0 if start exceeds len
   if (start >= len)
      return 0;
   // If value is not calculated for start index
       // Add current string
      int sol1 = str_array[start].size() + maxStringSize(str_array, len, 
(start + str_array
[start].size() / 2) + 1);
      // Remove current string
      int sol2 = maxStringSize(str_array, len, start + 1);
      // Take max of both
      int maxSize = max(sol1, sol2);
   // return answer
   return maxSize;
}
int main() {
   string str_array[] = {"tutor", "po", "nt", "welco", "ghj"};
   int len = sizeof(str_array) / sizeof(str_array[0]);
   cout << "The maximum size of the resultant string according to given conditions is  - " << maxStringSize(str_array, len, 0);
   return 0;
}

输出

The maximum size of the resultant string according to given conditions is - 10

时间复杂度 - O(2^N),因为我们在递归函数中为所有字符串做出选择。

空间复杂度 - O(1),因为我们使用了常数空间。

方法2

这种方法将使用记忆化技术来解决问题。它将先前计算出的结果存储在列表中。因此,如果我们需要再次计算相同的操作,就可以从列表中取值。

算法

步骤1 - 定义长度与数组长度相等的 ‘dp’ 列表,并将其初始化为 -1。

步骤2 - 如果开始位置大于数组长度,则返回0。

步骤3 - 如果 dp[start] 为 -1,我们第一次计算该值。

步骤4 - 执行递归函数调用。在一个函数调用中,包含开始索引处的字符串;在另一个函数调用中,不包含开始索引处的字符串。

步骤5 - 将两个解决方案中的最大值存储在 dp[start] 中。

步骤6 - 返回 dp[start] 的值。

例子

#include <bits/stdc++.h>
using namespace std;

int maxStringSize(string str_array[], int len, int start, vector<int> 
&dp) {
   // Return 0 if start exceeds len
   if (start >= len)
      return 0;
   // If value is not calculated for start index
   if (dp[start] == -1) {
      // Add current string
      int sol1 = str_array[start].size() + maxStringSize(str_array, len, 
(start + str_array[start].size() / 2) + 1, dp);
      // Remove current string
      int sol2 = maxStringSize(str_array, len, start + 1, dp);
      // Take max of both
      dp[start] = max(sol1, sol2);
   }
   // return answer
   return dp[start];
}
int main() {
   string str_array[] = {"tutor", "po", "nt", "welco", "ghj"};
   int len = sizeof(str_array) / sizeof(str_array[0]);
   vector<int> dp(len, -1);
   cout << "The maximum size of the resultant string according to given conditions is " << maxStringSize(str_array, len, 0, dp);
   return 0;
}

输出

The maximum size of the resultant string according to given conditions is 10

时间复杂度 – O(N*M),其中N是数组的长度,M是字符串的最大长度。

空间复杂度 – O(N),因为我们为每个起始索引存储结果值。

方法3

在这种方法中,我们将使用动态规划的表格方法来解决问题。它通过迭代填充列表并根据先前状态决定答案。

算法

步骤1 - 定义’matrix’列表。

步骤2 - 将matrix的最后一个元素初始化为0。

步骤3 - 从最后一个索引开始遍历数组。

步骤4 - 将sol1变量初始化为字符串大小。如果p + str_array[p].size() / 2 + 1小于或等于数组长度,则从matrix的(p + str_array[p].size() / 2 + 1)索引处将值添加到sol1。

步骤5 - 定义’sol2’并将其初始化为matrix[p+1]。

步骤6 - 在matrix[p]中存储sol1和sol2的最大值。

步骤7 - 返回matrix[0]的值。

例子

#include <bits/stdc++.h>
using namespace std;

int maxStringSize(string str_array[], int len) {
   // List to store results
   vector<int> matrix(len + 1);
   matrix[len] = 0; // Initialization
   // Traverse the string
   for (int p = len - 1; p >= 0; p--) {
      // Include string at pth index
      int sol1 = str_array[p].size();
      if (p + str_array[p].size() / 2 + 1 <= len) {
         sol1 += matrix[p + str_array[p].size() / 2 + 1];
      }
      // Don't include string at pth index
      int sol2 = matrix[p + 1];
      // Answer for last p strings
      matrix[p] = max(sol1, sol2);
   }
   // Return final result
   return matrix[0];
}
int main() {
   string str_array[] = {"tutor", "po", "nt", "welco", "ghj"};
   int len = sizeof(str_array) / sizeof(str_array[0]);
   cout << "The maximum size of the resultant string according to given conditions is " << maxStringSize(str_array, len);
   return 0;
}

输出

The maximum size of the resultant string according to given conditions is 10

时间复杂度 - 遍历字符串,时间复杂度为O(N)。

空间复杂度 - 使用列表存储前面的结果,空间复杂度为O(N)。

从上述三种方法来看,表格技术在时间复杂度方面最好。记忆化技术是递归方法的优化版本,因为我们使用了先前计算出的结果。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程