代码随想录-字符串01 344.反转字符串&541. 反转字符串II&替换空格&翻转字符串里的单词&左旋转字符串

题目目录

● 344.反转字符串

● 541. 反转字符串II

● 剑指Offer 05.替换空格

● 151.翻转字符串里的单词

● 剑指Offer58-II.左旋转字符串

344.反转字符串

344.反转字符串

很经典的字符串考察点,考察对双指针的熟悉程度。

解法是通过双指针从字符串数组两边向中间靠拢,交换字符。

c++ 复制代码
void reverseString(vector<char>& s)
{
    int left = 0;
    int right = s.size() - 1;
    while (left < right) {
        char tmp = s[left];
        s[left] = s[right];
        s[right] = tmp;

        left++;
        right--;
    }
}

541. 反转字符串II

541. 反转字符串II

解题的思路比上一题复杂一点,但是思路还是一样的,不同之处在于外层多了循环。

c++ 复制代码
string reverseStringII(string s, int k)
{
    int strLen = s.size();
    int leftLen = strLen;
    while (leftLen > 0) {
        int left = strLen - leftLen;
        int right = left + k -1;
        if (leftLen < k) {
            right = strLen - 1;
        }
        while (left < right) {
            char tmp = s[left];
            s[left] = s[right];
            s[right] = tmp;

            left++;
            right--;
        }
        leftLen = leftLen - 2 * k;
    }

    return s;
}

剑指Offer 05.替换空格

剑指Offer 05.替换空格

主要思路是先统计空格个数,对数组扩容,利用双指针从数组尾部往前填充

c++ 复制代码
string replaceBlackChar(string s)
{
    // 获取空格个数
    int spaceCount = 0;
    for (int i = 0; i < s.size(); ++i) {
        if (s[i] == ' ')
            spaceCount++;
    }
    int strLen = s.size();
    // 扩容
    s.resize(strLen + spaceCount * 2);
    // 双指针移动
    int left = strLen - 1;
    int right = s.size() - 1;

    while (left >= 0) {
        if (s[left] == ' ')
        {
            s[right--] = '0';
            s[right--] = '2';
            s[right--] = '%';
        } else {
            s[right--] = s[left];
        }
        left--;
    }
    return s;
}

151.翻转字符串里的单词

151.翻转字符串里的单词

思路是找到空格,分割单词,然后填充到str

O(n + n) 空间 O(n)

c++ 复制代码
string reverseWord(string str)
{
    vector<string> vec;

    int index = 0;
    int ret = 0;
    while ((ret = str.find(' ', index)) != str.npos) {
        vec.push_back(str.substr(index, ret - index));
        index = ret + 1;
    }
    index = str.size() - 1;
    for (auto val : vec) {
        for (auto i = val.size() - 1; i >= 0; --i) {
            str[index--] = val[i];
        }
        if (index > 0)
            str[index--] = ' ';
    }
    return str;
}

上面的解法使用到了O(n)的额外空间及substr字符串函数,尽量别使用库函数来实现。

下面是高效解法:

c++ 复制代码
// 思路:
// 删除多余空格
// 从后往前移动,覆盖掉多余空格
// 就是数组元素删除操作
string removeExtraSpace(string s)
{
    int slow = 0;
    for (int i = 0; i < s.size(); ++i) {
        if (s[i] != ' ') {
            if (slow != 0) s[slow++] = ' ';
            while (i < s.size() && s[i] != ' ') {
                s[slow++] = s[i++];
            }
        }
    }
    s.resize(slow);
    return s;
}

//
string reverseWord2(string s)
{
    // 去除多余空格
    s = removeExtraSpace(s);
    // 反转
	int left = 0;
    int right = s.size() - 1;
	while (left < right) {
        char ch = s[left];
        s[left++] = s[right];
        s[right--] = ch;
	}
    // 单词反转
	left = 0;
    while (left < s.size()) {
		right = left + 1;
        while (right < s.size() && s[right] != ' ')
			right++;
		int tmp = right;
        right -= 1;
        while (left < right) {
            char ch = s[left];
            s[left++] = s[right];
            s[right--] = ch;
		}
		
		left = tmp + 1;
	}
    return s;
}

剑指Offer58-II.左旋转字符串

剑指Offer58-II.左旋转字符串

c++ 复制代码
//
string leftReverseString(string s, int n)
{
    // 整体反转
    int left  = 0;
    int right = s.size() - 1;
    while (left < right) {
        char ch = s[left];
        s[left++] = s[right];
        s[right--] = ch;
    }
    // 最后n个字符反转
    left = s.size() - n;
    right = s.size() - 1;
    while (left < right) {
        char ch = s[left];
        s[left++] = s[right];
        s[right--] = ch;
    }
    // 剩下字符反转
    left = 0;
    right = s.size() - n - 1;
    while (left < right) {
        char ch = s[left];
        s[left++] = s[right];
        s[right--] = ch;
    }

    return s;
}
相关推荐
草莓熊Lotso2 分钟前
Linux 文件描述符与重定向实战:从原理到 minishell 实现
android·linux·运维·服务器·数据库·c++·人工智能
历程里程碑6 分钟前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法
YGGP1 小时前
【Golang】LeetCode 128. 最长连续序列
leetcode
你撅嘴真丑7 小时前
第九章-数字三角形
算法
在路上看风景7 小时前
19. 成员初始化列表和初始化对象
c++
uesowys7 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
zmzb01038 小时前
C++课后习题训练记录Day98
开发语言·c++
ValhallaCoder8 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮8 小时前
AI 视觉连载1:像素
算法
念风零壹8 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++