代码随想录-字符串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;
}
相关推荐
sali-tec1 天前
C# 基于halcon的视觉工作流-章66 四目匹配
开发语言·人工智能·数码相机·算法·计算机视觉·c#
小明说Java1 天前
常见排序算法的实现
数据结构·算法·排序算法
45288655上山打老虎1 天前
C++完美转发
java·jvm·c++
行云流水20191 天前
编程竞赛算法选择:理解时间复杂度提升解题效率
算法
SunkingYang1 天前
程序崩溃闪退——MFC共享内存多次OpenFileMapping和MapViewOfFile而没有相应的UnmapViewOfFile和CloseHandle
c++·mfc·共享内存·崩溃·闪退·close·openfilemapping
问君能有几多愁~1 天前
C++ 日志实现
java·前端·c++
smj2302_796826521 天前
解决leetcode第3768题.固定长度子数组中的最小逆序对数目
python·算法·leetcode
JANGHIGH1 天前
c++ 多线程(二)
开发语言·c++
珑墨1 天前
【浏览器】页面加载原理详解
前端·javascript·c++·node.js·edge浏览器
cynicme1 天前
力扣3531——统计被覆盖的建筑
算法·leetcode