【算法集训 | 暑期刷题营】8.13题---字符串

简介: 【算法集训 | 暑期刷题营】8.13题---字符串

 👉引言


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


💖 ❄️我们的算法之路❄️💖


   众所周知,作为一名合格的程序员,算法 能力 是不可获缺的,并且在算法学习的过程中我们总是能感受到算法的✨魅力✨。

☀️🌟短短几行代码,凝聚无数前人智慧;一个普通循环,即是解题之眼🌟☀️

💝二分,💝贪心,💝并查集,💝二叉树,💝图论,💝深度优先搜索(dfs) ,💝宽度优先搜索(bfs) ,💝数论,💝动态规划等等, 路漫漫其修远兮,吾将上下而求索! 希望在此集训中与大家共同进步,有所收获!!!🎉🎉🎉

image.png


今日主题:字符串


 👉⭐️第一题💎


   ✨题目


     1.反转字符串||

image.png

   ✨思路:


简单的字符串模拟题,简单来说就是翻转前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小的数字

image.png


   ✨思路:


数字字符串都是等长的,把索引拼接到数据上。比较大小时,传入。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.设置文本编辑器

image.png


   ✨思路:


用两个栈模拟光标的移动,右边的栈,下标顺序是逆序的,这样,往右边放入或取字符时,才可以直接在栈顶位置进行操作,左边的栈顶位置,记得补充一个结束符,这样,在光标左移、右移的操作过程中,需要返回左侧至多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


image.pngimage.png


   ✨代码:


#include<bits/stdc++.h>
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';
    }
}

🌹写在最后💖

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


相关文章
|
5天前
|
存储 算法 C语言
【数据结构与算法 刷题系列】合并两个有序链表
【数据结构与算法 刷题系列】合并两个有序链表
|
16天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
4天前
|
存储 算法 Java
Java数据结构与算法:用于高效地存储和检索字符串数据集
Java数据结构与算法:用于高效地存储和检索字符串数据集
|
5天前
|
算法
【数据结构与算法 刷题系列】求带环链表的入环节点(图文详解)
【数据结构与算法 刷题系列】求带环链表的入环节点(图文详解)
|
5天前
|
算法
【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
【数据结构与算法 刷题系列】判断链表是否有环(图文详解)
|
5天前
|
算法
【数据结构与算法 刷题系列】移除链表元素
【数据结构与算法 刷题系列】移除链表元素
|
5天前
|
存储 算法 C语言
【数据结构与算法 刷题系列】环形链表的约瑟夫问题
【数据结构与算法 刷题系列】环形链表的约瑟夫问题
|
5天前
|
算法 C语言
【数据结构与算法 刷题系列】求链表的中间结点
【数据结构与算法 刷题系列】求链表的中间结点
|
6天前
|
算法 Java
Java数据结构与算法:字符串匹配算法之暴力匹配
Java数据结构与算法:字符串匹配算法之暴力匹配
|
6天前
|
算法 Java
Java数据结构与算法:字符串匹配算法之KMP算法
Java数据结构与算法:字符串匹配算法之KMP算法