【算法集训暑期刷题营】7.23日题---字符串

算法集训传送门》

  引言

在这里插入图片描述

铭记于心
我唯一知道的,便是我一无所知

❄️我们的算法之路❄️

   众所周知,作为一名合格的程序员,算法 能力 是不可获缺的,并且在算法学习的过程中我们总是能感受到算法的✨魅力✨。
              ☀️短短几行代码,凝聚无数前人智慧;一个普通循环,即是解题之眼☀️
   二分贪心并查集二叉树图论深度优先搜索(dfs)宽度优先搜索(bfs)数论动态规划等等, 路漫漫其修远兮,吾将上下而求索! 希望在此集训中与大家共同进步,有所收获!!!

在这里插入图片描述


今日主题:字符串


 ⭐️第一题

   ✨题目

      1.反转字符串||
【算法集训暑期刷题营】7.23日题---字符串_第1张图片

   ✨思路

简单的字符串模拟题,简单来说就是翻转前K个字符,前后指针边向中间遍历边交换,可以自定义一个swap(),对于C++来说可以直接用STL的reverse函数

   ✨代码
class Solution {
    public String reverseStr(String s, int k) {
        char[] cs = s.toCharArray();
        int n = s.length();
        for (int l = 0; l < n; l = l + 2 * k) {
            int r = l + k - 1;
            reverse(cs, l, Math.min(r, n - 1));
        }
        return String.valueOf(cs);
    }
    void reverse(char[] cs, int l, int r) {
        while (l < r) {
            char c = cs[l];
            cs[l] = cs[r];
            cs[r] = c;
            l++; r--;
        }
    }
}


 ⭐️第二题

   ✨题目

       2.裁剪数字后查询第k小的数字

【算法集训暑期刷题营】7.23日题---字符串_第2张图片

   ✨思路

数字字符串都是等长的,把索引拼接到数据上。比较大小时,传入。nums[0].length()-queries[i][1]就是从截取位置之后开始比较。这样好处是在不稳定的排序中后面拼接的索引确保了,每一个数据的唯一性,所以即使不稳定,它也可以正确的找出第k小。这就为选用选择排序铺平了道路。这里我们选择归并排序。

   ✨代码
class Solution {
public:
    vector<int> smallestTrimmedNumbers(vector<string> &nums, vector<vector<int>> &queries) {
        vector<int> ans(queries.size());
        int n = nums.size(), m = nums[0].length();
        int idx[n];
        for (int i = 0; i < queries.size(); ++i) {
            auto &q = queries[i];
            iota(idx, idx + n, 0);
            stable_sort(idx, idx + n, [&](int a, int b) {
                auto &s = nums[a], &t = nums[b];
                for (int j = m - q[1]; j < m; ++j)
                    if (s[j] != t[j]) return s[j] < t[j];
                return false;
            });
            ans[i] = idx[q[0] - 1];
        }
        return ans;
    }
};


 ⭐️第三题

   ✨题目

      3.设置文本编辑器
【算法集训暑期刷题营】7.23日题---字符串_第3张图片

   ✨思路

用两个栈模拟光标的移动,右边的栈,下标顺序是逆序的,这样,往右边放入或取字符时,才可以直接在栈顶位置进行操作,左边的栈顶位置,记得补充一个结束符,这样,在光标左移、右移的操作过程中,需要返回左侧至多10个字符时,可以直接返回子字符串的开始下标,到结束符为止即可输出

   ✨代码
#define MAX_STACKSIZE 800000
#define ATMOST_LENGTH 10
#define MIN_VALUE(x, y) (((x) < (y)) ? (x) : (y))

/* leftSize表示左侧栈已用空间,left表示左侧栈,rightSize表示右侧栈已用空间,right表示右侧栈。 */
typedef struct
{
    int leftSize;
    int rightSize;
    char *left;
    char *right;
}
TextEditor;

/* 创建对象,并初始化。 */
TextEditor *textEditorCreate()
{
    TextEditor *obj = (TextEditor *)malloc(sizeof(TextEditor));

    obj->leftSize = 0;
    obj->rightSize = 0;
    obj->left = (char *)malloc(sizeof(char) * MAX_STACKSIZE);
    obj->right = (char *)malloc(sizeof(char) * MAX_STACKSIZE);
    return obj;
}

/* 从光标所在位置开始,插入文本。 */
void textEditorAddText(TextEditor *obj, char *text)
{
    int x = 0;

    /* 此时只需要操作左侧栈。 */
    while('\0' != text[x])
    {
        obj->left[obj->leftSize] = text[x];
        obj->leftSize++;
        x++;
    }
    /* 栈顶位置用结束符补充。 */
    obj->left[obj->leftSize] = '\0';
    return;
}

/* 删除k个字符。 */
int textEditorDeleteText(TextEditor *obj, int k)
{
    /* 左侧栈不足k个时,全部删光。 */
    int x = MIN_VALUE(obj->leftSize, k);

    obj->leftSize -= x;
    /* 栈顶位置用结束符补充。 */
    obj->left[obj->leftSize] = '\0';
    return x;
}

/* 光标向左移动k次。 */
char *textEditorCursorLeft(TextEditor *obj, int k)
{
    int index = 0;

    /* 每移动一次,左侧栈顶的字符就移动到右侧栈顶。 */
    while(0 < k && 0 < obj->leftSize)
    {
        obj->leftSize--;
        obj->right[obj->rightSize] = obj->left[obj->leftSize];
        obj->rightSize++;
        k--;
    }
    /* 栈顶位置用结束符补充。 */
    obj->left[obj->leftSize] = '\0';
    /* 返回左侧长度最多为10的子字符串。 */
    if(ATMOST_LENGTH < obj->leftSize)
    {
        index = obj->leftSize - ATMOST_LENGTH;
    }
    return &obj->left[index];
}

/* 光标向右移动k次。 */
char *textEditorCursorRight(TextEditor *obj, int k)
{
    int index = 0;

    /* 每移动一次,右侧栈顶的字符就移动到左侧栈顶。 */
    while(0 < k && 0 < obj->rightSize)
    {
        obj->rightSize--;
        obj->left[obj->leftSize] = obj->right[obj->rightSize];
        obj->leftSize++;
        k--;
    }
    /* 栈顶位置用结束符补充。 */
    obj->left[obj->leftSize] = '\0';
    /* 返回左侧长度最多为10的子字符串。 */
    if(ATMOST_LENGTH < obj->leftSize)
    {
        index = obj->leftSize - ATMOST_LENGTH;
    }
    return &obj->left[index];
}

/* 释放对象。 */
void textEditorFree(TextEditor *obj)
{
    free(obj->left);
    free(obj->right);
    free(obj);
    return;
}




 ⭐️第四题

   ✨题目

      4. Roof Construction
【算法集训暑期刷题营】7.23日题---字符串_第4张图片
在这里插入图片描述

   ✨代码
#include
using namespace std;
 
 
int main() {
    int t;
    cin >> t;
    while(t--) {
        int n;
        cin >> n;
        int k = 0;
        while((1 << (k + 1)) <= n - 1) ++k; 
        for(int i = (1 << k) - 1; i >= 0; i--) {
            cout << i << ' ';
        }
        for(int i = (1 << k); i < n; i++) {
            cout << i << ' ';
        }
        cout << '\n';
    }
}

写在最后
相信大家对今天的集训内容的理解与以往已经有很大不同了吧,或许也感受到了算法的魅力,当然这是一定的,路漫漫其修远兮,吾将上下而求索!伙伴们,明天见!在这里插入图片描述

你可能感兴趣的:(算法集训,算法,深度优先,leetcode)