豆包Al练中学刷题感悟

152 阅读3分钟

题目描述

小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。

例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。

现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。

测试样例

样例1:

输入:n = 5, k = 2, s = "01010"
输出:'00101'

样例2:

输入:n = 7, k = 3, s = "1101001"
输出:'0110101'

样例3:

输入:n = 4, k = 1, s = "1001"
输出:'0101'

思路

解题思路

  1. 理解问题:首先需要通过交换相邻字符来最小化字符串的字典序。每次交换可以改变字符串的顺序,但需要在 k 次操作内完成。

  2. 选择数据结构:可以使用一个数组来表示字符串,这样可以方便地进行交换操作。

  3. 算法步骤

    • 遍历字符串,找到当前最小的字符。
    • 计算将这个最小字符移动到当前位置所需的最小交换次数。
    • 如果交换次数不超过 k,则进行交换,并更新 k
    • 继续遍历字符串的剩余部分,重复上述步骤。

c++代码

#include <iostream>
#include <vector>
#include <string>

using namespace std;

string solution(int n, int k, string s) {
    // 将字符串转换为字符数组,方便进行交换操作
    vector<char> chars(s.begin(), s.end());
    
    // 遍历字符串
    for (int i = 0; i < n; ++i) {
        // 找到从当前位置 i 开始的最小字符
        int minIndex = i;
        for (int j = i + 1; j < n; ++j) {
            if (chars[j] < chars[minIndex]) {
                minIndex = j;
            }
        }
        
        // 计算将最小字符移动到当前位置 i 所需的交换次数
        int swapsNeeded = minIndex - i;
        
        // 如果交换次数不超过 k,则进行交换
        if (swapsNeeded <= k) {
            // 将最小字符移动到当前位置 i
            while (minIndex > i) {
                swap(chars[minIndex], chars[minIndex - 1]);
                minIndex--;
            }
            // 更新剩余的交换次数
            k -= swapsNeeded;
        }
    }
    
    // 将字符数组转换回字符串并返回
    return string(chars.begin(), chars.end());
}

int main() {
    cout << (solution(5, 2, "01010") == "00101") << endl;
    cout << (solution(7, 3, "1101001") == "0110101") << endl;
    cout << (solution(4, 1, "1001") == "0101") << endl;
    return 0;
}

关键步骤

  1. 找到最小字符:在当前位置 i 之后的子字符串中找到最小的字符。
  2. 计算交换次数:计算将这个最小字符移动到当前位置 i 所需的交换次数。
  3. 执行交换:如果交换次数不超过 k,则进行交换,并更新 k

时间复杂度分析

  1. 外层循环

    • 外层循环遍历字符串的每个字符,循环次数为 n
  2. 内层循环

    • 在每次外层循环中,内层循环从当前位置 i 开始,找到从 i 到 n-1 的最小字符。这个内层循环的次数为 n - i
  3. 交换操作

    • 如果找到的最小字符需要交换到当前位置 i,则进行交换操作。交换操作的次数为 minIndex - i,在最坏情况下,这个值可以达到 n - i

总时间复杂度

  • 内层循环:每次内层循环的次数为 n - i,总的时间复杂度为 O(n^2)
  • 交换操作:在最坏情况下,每次交换操作的次数为 n - i,总的时间复杂度为 O(n^2)

因此,总的时间复杂度为 O(n^2)

总结

当前代码的时间复杂度为 O(n^2),这是因为在最坏情况下,每次外层循环都需要遍历剩余的字符串来找到最小字符,并且可能需要进行多次交换操作。这是目前的一个思路, 可能后续会有更好的想法