从C语言到C++_12(string相关OJ题)(leetcode力扣)

简介: 从C语言到C++_12(string相关OJ题)(leetcode力扣)

上一篇已经讲了string类的接口函数,然后根据查文档刷了牛客和力扣58最后一个单词的长度,

还有力扣415字符串相加,这篇继续跟着查文档来刷力扣题,体会C++刷题的方便。

917. 仅仅反转字母 - 力扣(LeetCode)

难度简单

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。
  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s

示例 1:

输入:s = "ab-cd"

输出:"dc-ba"

示例 2:

输入:s = "a-bC-dEf-ghIj"

输出:"j-Ih-gfE-dCba"

示例 3:

输入:s = "Test1ng-Leet=code-Q!"

输出:"Qedo1ct-eeLg=ntse-T!"

提示

  • 1 <= s.length <= 100
  • s 仅由 ASCII 值在范围 [33, 122] 的字符组成
  • s 不含 '\"''\\'
class Solution {
public:
    string reverseOnlyLetters(string s) {
 
    }
};

代码解析:

这道题和快排的思路很类似,swap不知道有没有讲过在algorithm这个头文件里有,和我们在函数模板实现的差不多,这种常用的肯定能想起来了,像判断是不是字母等函数,想不起来可以自己写,想起来不清楚可以查文档:


e45022ba02e34e3d92a64b71c9ce0865.png

class Solution {
public:
    string reverseOnlyLetters(string s) {
        int left  = 0,right = s.size() - 1;
        while(left < right)
        {
            while(left < right && !isalpha(s[left]))// 找字母,注意越界
            {
                ++left;
            }
            while(left < right && !isalpha(s[right]))
            {
                --right;
            }
            swap(s[left++],s[right--]);// 交换后往中间走,传引用,
        }
        return s;
    }
};

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

难度简单

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

示例 1:

输入: s = "leetcode"

输出: 0

示例 2:

输入: s = "loveleetcode"

输出: 2

示例 3:

输入: s = "aabb"

输出: -1

提示:

1 <= s.length <= 10^5

s 只包含小写字母

class Solution {
public:
    int firstUniqChar(string s) {
        
    }
};

解析代码:

可以暴力查找,是O(N^2),只有小写字母,可以用计数排序的思想:

class Solution {
public:
  int firstUniqChar(string s) {
    int countArr[26] = { 0 };
    for (auto e : s)
    {
      countArr[e-'a']++;//相对映射到数组里++
    }
    for (int i = 0;i < s.size(); i++)
    {
      if (countArr[(s[i]-'a')] == 1)//从原字符串遍历字符的相对映射
      {
        return i;//第一个相对映射为1的就返回其下标
      }
    }
    return -1;//没有出现一次的,输出-1
  }
};

125. 验证回文串 - 力扣(LeetCode)

难度简单

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 

示例 1:

输入: s = "A man, a plan, a canal: Panama"

输出:true

解释:"amanaplanacanalpanama" 是回文串。

示例 2:

输入:s = "race a car"

输出:false

解释:"raceacar" 不是回文串。

示例 3:

输入:s = " "

输出:true

解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。

由于空字符串正着反着读都一样,所以是回文串。

提示:

  • 1 <= s.length <= 2 * 10^5
  • s 仅由可打印的 ASCII 字符组成
class Solution {
public:
    bool isPalindrome(string s) {
 
    }
};

代码解析:

此题和快排思路类似,从两边找字符,判断是否相等,这题可能刚看会有其它思路,但把全部大写字母转成小写字母,或者反过来都是很方便的,动手动手:

class Solution {
public:
    bool isPalindrome(string s) {
        for(auto& e : s)
        {
            e = tolower(e);// 如果是大写就转小写,不是大写就不处理
        }
        int left = 0,right = s.size() - 1;
        while(left < right )//找字母数字字符后比较
        {
            while(left < right && !isalpha(s[left]) && !isdigit(s[left]))
            {
                left++;
            }
            while(left < right && !isalpha(s[right]) && !isdigit(s[right]))
            {
                right--;
            }
            if(s[left] != s[right])
            {
                return false;
            }
            else
            {
                left++;
                right--;
            }
        }
        return true;
    }
};

344. 反转字符串 - 力扣(LeetCode)

难度简单

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,

你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]

输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]

输出:["h","a","n","n","a","H"]

提示:

  • 1 <= s.length <= 10^5
  • s[i] 都是 ASCII 码表中的可打印字符
class Solution {
public:
    void reverseString(vector<char>& s) {
 
    }
};

解析代码:

可以说我们以前都实现过了,就是这里变成了vector,

这里的vector就是一个存char类型的数组,我们收尾交换,进行翻转:

class Solution {
public:
    void reverseString(vector<char>& s) {
        int left = 0,right = s.size() - 1;
        while(left < right)
        {
            swap(s[left++],s[right--]);
        }
    }
};

541. 反转字符串 II - 力扣(LeetCode)

难度简单

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,

就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例 1:

输入:s = "abcdefg", k = 2


输出:"bacdfeg"

示例 2:

输入:s = "abcd", k = 2

输出:"bacd"

提示:

  • 1 <= s.length <= 10^4
  • s 仅由小写英文组成
  • 1 <= k <= 10^4
class Solution {
public:
    string reverseStr(string s, int k) {
 
    }
};

解析代码:

题目确实有点难懂,人话:每隔k个反转k个,末尾不够k个时全部反转。

一顿试错后的代码:

class Solution {
public:
    void reverseString(string& s,int left,int right) {
        while(left < right)
        {
            swap(s[left++],s[right--]);
        }
    }
    string reverseStr(string s, int k) {
        for(size_t i = 0; i < s.size(); i += 2*k)
        {
            if(i + k > s.size())
            {
                reverseString(s,i,s.size() - 1);
            }
            else
            {
                reverseString(s,i,i + k - 1);
            }
        }
        return s;
    }
};

还可以用官方库里面的左闭右开(上面实现的是左闭右闭)的reverse函数:

class Solution {
public:
    void reverseString(string& s,int left,int right) {
        while(left < right)
        {
            swap(s[left++],s[right--]);
        }
    }
    string reverseStr(string s, int k) {
        for(size_t i = 0; i < s.size(); i += 2*k)
        {
            if(i + k > s.size())
            {
                //reverseString(s,i,s.size() - 1);
                reverse(&s[i],&s[s.size()]);
            }
            else
            {
                //reverseString(s,i,i + k - 1);
                reverse(&s[i],&s[i + k]);
            }
        }
        return s;
    }
};

557. 反转字符串中的单词 III - 力扣(LeetCode)

难度简单

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,

同时仍保留空格和单词的初始顺序。

示例 1:

输入:s = "Let's take LeetCode contest"

输出:"s'teL ekat edoCteeL tsetnoc"

示例 2:

输入: s = "God Ding"

输出:"doG gniD"

提示:

  • 1 <= s.length <= 5 * 10^4
  • s 包含可打印的 ASCII 字符。
  • s 不包含任何开头或结尾空格。
  • s至少 有一个词。
  • s 中的所有单词都用一个空格隔开。
class Solution {
public:
    string reverseWords(string s) {
 
    }
};

解析代码:

(类似双指针的思想:)

class Solution {
public:
    string reverseWords(string s) {
        size_t left = 0,right = 0;
        while(left < s.size())
        {
            while(right < s.size() && s[right] != ' ')// 找空格/结尾,要先判断结尾,防止越界访问
            {
                ++right;
            }
            reverse(&s[left],&s[right]);// 注意是左闭右开(反正我是服了)
            ++right;//跳过空格,进行下一次判断
            left = right;
        }
        return s;
    }
};

43. 字符串相乘 - 力扣(LeetCode)

难度中等

给定两个以字符串形式表示的非负整数 num1num2,返回 num1num2 的乘积,

它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

示例 1:

输入: num1 = "2", num2 = "3"

输出: "6"

示例 2:

输入: num1 = "123", num2 = "456"

输出: "56088"

提示:

  • 1 <= num1.length, num2.length <= 200
  • num1num2 只能由数字组成。
  • num1num2 都不包含任何前导零,除了数字0本身。
class Solution {
public:
    string multiply(string num1, string num2) {
 
    }
};


解析代码:

这题有点难就看题解了,这里用方法二:

class Solution {
public:
  string multiply(string num1, string num2) {
    int n = num1.size(), m = num2.size();
    vector<int> v(n + m, 0);//开n+m个0
    for (int i = 0; i < n; ++i)
    {
      for (int j = 0; j < m; ++j)
      {
        int a = num1[n - i - 1] - '0';
        int b = num2[m - j - 1] - '0';
        v[i + j] += a * b;
      }
    }
    for (int i = 0, carry = 0; i < v.size();++i)//carry进位
    {
      v[i] += carry;
      carry = v[i] / 10;
      v[i] %= 10;
    }
    string ret;
    for (int i = v.size() - 1;i >= 0;--i)
    {
      if (ret.empty() && v[i] == 0)//如果ret是空的,并且v[i] == 0,就是前导0的情况
      {
        continue;
      }
      ret += (v[i] + '0');
    }
    return ret.empty() ? "0" : ret;//如果是空串就返回0,也可以在开头判断
  }
};

本章完。

下一篇:模拟实现string,深拷贝浅拷贝,拷贝构造和赋值重载的传统写法和现代写法。

目录
相关文章
|
18天前
|
对象存储 C++ 容器
c++的string一键介绍
这篇文章旨在帮助读者回忆如何使用string,并提醒注意事项。它不是一篇详细的功能介绍,而是一篇润色文章。先展示重载函数,如果该函数一笔不可带过,就先展示英文原档(附带翻译),最后展示代码实现与举例可以直接去看英文文档,也可以看本篇文章,但是更建议去看英文原档。那么废话少说直接开始进行挨个介绍。
|
4月前
|
存储 安全 C语言
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
|
18天前
|
Java C++
力扣第一道困难题《3. 无重复字符的最长子串》,c++
首先我们看到这个题是肯定有一种暴力的硬解思路的,那就是将两个vector直接链接起来,然后再排序后,直接返回中间值,这个方法实现起来还是非常容易的,
|
4月前
|
C++
模拟实现c++中的string
模拟实现c++中的string
|
7月前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
332 5
|
7月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
224 2
|
8月前
|
C++ 容器
|
6月前
|
算法 编译器 C语言
【C语言】C++ 和 C 的优缺点是什么?
C 和 C++ 是两种强大的编程语言,各有其优缺点。C 语言以其高效性、底层控制和简洁性广泛应用于系统编程和嵌入式系统。C++ 在 C 语言的基础上引入了面向对象编程、模板编程和丰富的标准库,使其适合开发大型、复杂的软件系统。 在选择使用 C 还是 C++ 时,开发者需要根据项目的需求、语言的特性以及团队的技术栈来做出决策。无论是 C 语言还是 C++,了解其优缺点和适用场景能够帮助开发者在实际开发中做出更明智的选择,从而更好地应对挑战,实现项目目标。
267 0
|
8月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
70 1
|
8月前
|
C++ 容器

热门文章

最新文章