博客
关于我
BZOJ2176Strange string——最小表示法
阅读量:798 次
发布时间:2023-03-28

本文共 2048 字,大约阅读时间需要 6 分钟。

为了找到字符串中的最小长度为n的子串,可以采用以下贪心算法:

  • 预处理最小值数组:首先,预处理一个数组min_right,其中min_right[i]表示从位置i到字符串末尾的最小字符。

  • 遍历字符串:从左到右遍历字符串,使用两个指针leftright,维护一个窗口,确保窗口长度为n。

  • 滑动窗口:在滑动窗口中找到最小的字符,并记录该字符的位置。然后,移动左指针以缩小窗口,继续寻找更小的子串。

  • 记录最小子串:在每次找到更小的子串时,更新结果字符串。

  • 以下是具体实现步骤:

    • 预处理min_right数组:从右到左遍历字符串,记录每个位置的最小字符。
    • 初始化leftright指针,result字符串,和最小值位置min_pos
    • 滑动right指针,直到窗口长度等于n。
    • 在当前窗口中,找到最小字符及其位置k
    • 更新min_pos为当前窗口的最小字符位置。
    • left可以移动时,向右移动left,并重复上述步骤。

    以下是具体代码实现:

    #include 
    #include
    using namespace std;
    string findMinimalString(string s, int n) {
    int m = s.size();
    vector
    min_right(m, ' ');
    // 预处理 min_right数组
    for (int i = m - 1; i >= 0; --i) {
    if (i == m - 1) {
    min_right[i] = s[i];
    } else {
    min_right[i] = min(s[i], min_right[i + 1]);
    }
    }
    string result;
    int left = 0, right = 0;
    int min_pos = 0;
    while (right < m) {
    // 扩展右指针,直到窗口长度 >= n
    while (right - left + 1 < n && right < m) {
    right++;
    }
    // 在窗口[left, right]中找到最小字符
    int current_min = min_right[left];
    int current_min_pos = left;
    for (int i = left; i <= right; ++i) {
    if (s[i] < current_min) {
    current_min = s[i];
    current_min_pos = i;
    }
    }
    // 更新最小位置
    if (current_min_pos > min_pos) {
    min_pos = current_min_pos;
    }
    // 尝试移动左指针
    if (left <= min_pos && min_pos - left + 1 <= n) {
    left = min_pos + 1;
    }
    }
    // 构建结果字符串
    for (int i = 0; i < n; ++i) {
    result += s[min_pos - i];
    }
    return result;
    }
    int main() {
    int n;
    string s;
    // 读取输入
    n = 10;
    s = "asdfasdfas";
    string result = findMinimalString(s, n);
    cout << result << endl;
    return 0;
    }

    代码解释

  • 预处理min_right数组:从右到左遍历字符串,记录每个位置的最小字符。这一步的时间复杂度为O(m),其中m是字符串的长度。

  • 滑动窗口:使用两个指针leftright,确保窗口长度为n。在每次扩展窗口时,找到当前窗口内的最小字符及其位置。

  • 更新最小位置:记录当前窗口内的最小字符位置,确保在后续步骤中能够正确构建结果字符串。

  • 构建结果字符串:根据记录的最小位置,构建长度为n的最小子串。

  • 该算法的时间复杂度为O(m),适用于大数据量的处理。

    转载地址:http://hxhfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现ItemCF算法(附完整源码)
    查看>>
    Objective-C实现iterating through submasks遍历子掩码算法(附完整源码)
    查看>>
    Objective-C实现jaccard similarity相似度无平方因子数算法(附完整源码)
    查看>>
    Objective-C实现Julia集算法(附完整源码)
    查看>>
    Objective-C实现k nearest neighbours k最近邻分类算法(附完整源码)
    查看>>
    Objective-C实现k-Means算法(附完整源码)
    查看>>
    Objective-C实现k-nearest算法(附完整源码)
    查看>>
    Objective-C实现Knapsack problem背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knapsack背包问题算法(附完整源码)
    查看>>
    Objective-C实现knight tour骑士之旅算法(附完整源码)
    查看>>
    Objective-C实现KNN算法(附完整源码)
    查看>>
    Objective-C实现koch snowflake科赫雪花算法(附完整源码)
    查看>>
    Objective-C实现KPCA(附完整源码)
    查看>>
    Objective-C实现kth order statistick阶统计量算法(附完整源码)
    查看>>
    Objective-C实现LongestIncreasingSubsequence最长递增子序列算法(附完整源码)
    查看>>
    Objective-C实现LRU 缓存算法(附完整源码)
    查看>>
    Objective-C实现lstm prediction预测算法(附完整源码)
    查看>>
    Objective-C实现Luhn (Mod 10)Algorithm算法(附完整源码)
    查看>>
    Objective-C实现max subarray sum最大子数组和算法(附完整源码)
    查看>>