检查是否存在 2 * K + 1 个非空字符串,其连接构成给定的字符串


在这个问题中,我们给定一个字符串,我们需要将字符串分成 k + 1 个子字符串,使得 k + 1 个子字符串与其反转的连接可以给出原始字符串。

观察可以解决问题。如果字符串的前 k 个字符和后 k 个字符相同,我们可以说可以根据给定条件创建 k + 1 个字符串。

问题陈述 – 我们给定一个长度为 N 的字符串,包含小写字母字符和正整数 K。我们需要找到是否可以找到总共 k + 1 个字符串,使得字符串 A1、A2、A3、…、Ak、A(k + 1) 及其反转 AK、A(k-1)、…、A3、A2、A1 的连接是原始字符串 s。

示例

输入 – str = "tutorialsotut"; k = 4

输出 – 是

解释 – 我们可以创建总共 5 (4 + 1) 个字符串,分别是 't'、'u'、't'、'o' 和 'rials',当我们根据给定条件连接它们时,我们可以得到原始字符串。

输入 – str = "ststs", k = 1

输出 – 是

解释 – 我们可以创建 's' 和 'tst' 共 2 个字符串。

输入– str = “spres”, k = 3

输出– 否

解释 – 我们无法创建总共 4 个字符串,使其符合问题陈述中给出的条件。

方法 1

在这种方法中,我们将使用 for 循环来比较字符串的前 k 个字符与后 k 个字符。如果字符串的前 K 个字符等于后 k 个字符,我们可以说可以创建 K + 1 个字符串,因此当我们将它们按实际顺序和反向顺序合并时,我们可以得到原始字符串。

算法

  • 将字符串的长度存储在 'len' 变量中。

  • 如果 2*k + 1 大于字符串长度,则返回 false,因为无法通过按实际顺序和反向顺序合并 k + 1 个字符串来获得原始字符串。

  • 使用 for 循环遍历前 k 个字符和后 k 个字符。

  • 在循环中,比较 str[i] 和 str[len - i - 1] 字符。如果它们不相同,则返回 false。

  • 如果 for 循环完成所有迭代而没有执行 return 语句,则返回 true。

示例

#include <bits/stdc++.h>
using namespace std;
// function to check if we can make k+1 substrings to get the original string by concatenating strings according to the given conditions.
bool findStrings(string str, int k) {
   // get the length of the string
   int len = str.size();
   // If the length of the string is less than 2*k+1, return false
   if (2 * k + 1 > len) {
      return false;
   }
   // traverse the string to check whether the first k characters are equal to the reverse of the last k characters or not
   for (int i = 0; i < k; i++) {
      if (str[i] != str[len - i - 1]) {
          return false;
      }
   }
   // Return true if the first k characters are equal to the last k characters
   return true;
}
int main() {
   string str = "tutorialsotut";
   int K = 4;
   if (findStrings(str, K)) {
      cout << "Yes, we can make k+1 substrings according to the given conditions.";
   } else {
      cout << "No, we can't make k+1 substrings according to the given conditions.";
   }
   return 0;
}

输出

Yes, we can make k+1 substrings according to the given conditions.

时间复杂度 – O(K),因为我们遍历字符串的前 K 个字符。

空间复杂度 – O(1),因为我们使用常量空间。

方法 2

此方法使用 substr() 方法从原始字符串中获取子字符串。此外,我们将使用 reverse() 方法反转子字符串。

在这里,我们将比较前 k 个字符和后 k 个字符的反转。如果它们相等,我们可以说可以创建 k + 1 个子字符串,以便在合并后,我们可以得到实际字符串。

算法

  • 如果给定字符串的长度大于 2*k + 1,则返回 false。

  • 使用 substr() 方法并获取从 [0, k] 索引开始的子字符串,并将其存储到 'first' 变量中。

  • 再次使用 substr() 方法,获取从 [len - k, len] 索引开始的子字符串,并将其存储到 'last' 变量中。

  • 使用 reverse() 方法反转最后一个字符串。

  • 返回 first == last 的布尔值。

示例

#include <bits/stdc++.h>
using namespace std;
// function to check if we can make k+1 substrings so that we can get the original string by concatenating strings according to the given conditions.
bool findStrings(string str, int k) {
   // get the length of the string
   int len = str.size();
   // If the length of the string is less than 2*k+1, return false
   if (2 * k + 1 > len) {
      return false;
   }
   // Get the first k characters
   string first = str.substr(0, k);
   // Get the last k characters
   string last = str.substr(len - k, k);
   // Reverse the string
   reverse(last.begin(), last.end());
   // Return true if both the strings are equal. Otherwise, return false
   return (first == last);
}
int main() {
   string str = "ststs";
   int K = 1;
   if (findStrings(str, K)) {
      cout << "Yes, we can make k+1 substrings according to the given conditions.";
   } else {
      cout << "No, we can't make k+1 substrings according to the given conditions.";
   }
   return 0;
}

输出

Yes, we can make k+1 substrings according to the given conditions.

时间复杂度 – O(K),因为我们获取子字符串。

空间复杂度 – O(K),因为我们将长度为 K 的子字符串存储在 'first' 和 'last' 变量中。

我们学习了两种不同的方法来解决问题。第一种方法比第二种方法更优化,因为它具有更低的空间复杂度和相同的时间复杂度。

更新于: 2023年8月18日

63 次查看

开启你的 职业生涯

通过完成课程获得认证

开始
广告