如何在O(1)复杂度(运行时)中反转字符串?

roy*_*roy 6 algorithm

我今天接受了采访,并被要求在一次操作中反转一个字符串.我感觉不到O(n)就不可能了.顺便说一句,我有一个线索," 交换 "!所以...有答案吗?

  • 示例输入:"abcdefghi"(或任何字符串)
  • 样本输出:"ihgfedcba"
  • 不能使用内置功能.(例如:strrev())
  • 答案并不像反向打印/迭代那样棘手.

Pav*_*l P 6

您无法在时间上反转字符串O(1),但是可以通过O(1)空间复杂度来实现。

在单个操作中反转字符串

最有可能的是reverse it in one-liner,因为甚至不清楚“操作”到底是什么。

您可以使用std::reverse算法在一行中反转字符串

#include <string>
#include <algorithm>

int main()
{
    std::string str = "Hello world!";
    std::reverse(str.begin(), str.end());
    std::cout << "reverse is: \"" << str << '\"' << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

reverse is: "!dlrow olleH"
Run Code Online (Sandbox Code Playgroud)

或者你也可以使用一个简单的循环来做到这一点:

for (size_t i=0; i<str.size()/2; ++i)
    std::swap(str[i], str[str.size()-1-i);
Run Code Online (Sandbox Code Playgroud)

然而,这是O(N)运行时和O(1)空间(就像std::reverse)。

通常,简单的反向字符串算法问题的面试与一些技巧无关,很可能你的面试官希望看到这种循环的实现。另外,不要忘记面试官也是人,有时他们只是会犯错误并提出不可能的要求。或者,他们只是想让你说不可能反转 中的序列O(1)


Jes*_*uhl 1

反转字符串?只需从rbegin()迭代到rend(). 或者std::copy该范围为新字符串。“反转字符串”与原始字符串完全相同,只是以相反的方式读取。

  • 我认为 Jesper 想说的是,如果可以将“反转字符串”定义为反向解释现有字符串,那么“反转字符串”实际上可以是无操作。在这种情况下,只需创建一对反向迭代器即可“反转”字符串——实际上并不是在存储中移动任何字符,而是创建一个可以反向迭代字符串的视图。 (5认同)
  • “迭代”听起来不像 O(1) (4认同)
  • 考虑到这个问题,我认为这个答案还不错。无论如何,您都需要迭代该字符串才能将其打印出来,因此不应将其包含在计算中。所以打印字符串通常就是打印`begin()`到`end()`。打印出相反的内容就是将 `rbegin()` 打印为 `rend()`。所以字符串在 O(1) 内被反转。 (3认同)