c++ - 如何查找所有以1开头和结尾的子串?

标签 c++ algorithm

给定一个由 0 和 1 组成的字符串,您必须找到该字符串中以 1 开头和结尾的所有子字符串。

例如,给定 0010110010,输出应该是六个字符串:

101
1011
1011001
11
11001
1001

显然有一个 O(N^2) 解决方案,但我正在寻找一个复杂度约为 O(N) 的解决方案。可能吗?

最佳答案

Obviously there is an O(N^2) solution, but I'm looking for a solution with complexity on the order of O(N). Is it possible?

k 为输入字符串中 1 的数量。那么就有O(k^2)这样的子串。枚举它们必须至少花费 O(k^2) 时间。如果k ~ N,那么枚举它们必须花费O(N^2)时间。

获得O(N)解决方案的唯一方法是添加ko(sqrt(N))的要求>。一般情况下不可能存在对 k 没有限制的 O(N) 解决方案。

实际的O(k^2)解决方案很简单:

std::string input = ...;

std::vector<size_t> ones;
ones.reserve(input.size());

// O(N) find the 1s
for (size_t idx = 0; idx < input.size(); ++idx) {
    if (input[idx] == '1') {
        ones.push_back(idx);
    }
}

// O(k^2) walk the indices
for (size_t i = 0; i < ones.size(); ++i) {
    for (size_t j = i+1; j < ones.size(); ++j) {
        std::cout << input.substr(i, j - i + 1) << '\n';
    }
}

更新我们必须考虑子字符串的长度以及子字符串的数量。所有字符串的总长度为 O(k * N),严格大于之前声明的 O(k^2) 界限。因此,在 k 上绑定(bind)的 o(sqrt(N)) 是不够的 - 我们实际上需要 kO(1) 以便产生 O(N) 解决方案。

关于c++ - 如何查找所有以1开头和结尾的子串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28330260/

相关文章:

c++ - 如果您在 .h 文件中包含某些内容,您是否必须再次包含相同的内容?

c++ - 如何逐步构建具有依赖关系的非二叉树

java - Java代码中亲和传播的实现

java - 查找二维数组或直方图的两个主要峰值和峰值之间的谷值

c++ - Xcode 上的 SDL2 代码设计问题

c++ - vector<double>::size_type 与 double

c++ - 将结构元素插入有序集失败

c++ - 使用 libcurl 通过 HTTP 从内存(而不是磁盘)发送文件

algorithm - 具有 Chebyshev 距离的 Dijkstra 算法

java - 卡支持的算法列表?