【LeetCode】string 类的几道简单题

简介: 【LeetCode】string 类的几道简单题

👉仅反转字母👈


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

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

返回反转后的 s 。

21cec3af02ed4f8499021feb5450c3cd.png

思路:这道题可以借助快排的思想,左边找出字母,右边找出字母,然后进行交换。如果不是字母,就继续找。


class Solution 
{
public:
    string reverseOnlyLetters(string s) 
    {
        size_t begin = 0;
        size_t end = s.size() - 1;
        while(begin < end)
        {
            // isalpha是判断是否是字母的函数接口
            while(begin < end && !isalpha(s[begin]))
            {
                ++begin;
            }
            while(begin < end && !isalpha(s[end]))
            {
                --end;
            }
            swap(s[begin], s[end]);
            ++begin;
            --end;
        }
        return s;
    }
};


a1d92978380f4a9185a6f65f6de983fa.png


👉字符串中的第一个唯一字符👈


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

d072b98864034dd3bb34cd5a780ade40.png


思路:可以借助哈希映射的思想,用一个数组统计每个字母出现的次数,然后再遍历字符串就能够知道那个字母是第一个唯一字符。


class Solution 
{
public:
    int firstUniqChar(string s) 
    {
        int count[26] = {0};
        // 统计字母出现的次数
        for(auto ch : s)
        {
            ++count[ch - 'a'];
        }
        // 顺序遍历字符串,找出第一个唯一字母
        for(int i = 0; i < s.size(); i++)
        {
            if(count[s[i] - 'a'] == 1)
                return i;            
        }
        return -1;
    }
};


7f831adb2a764acab58cfddb7d5ae9ce.png


👉字符串相加👈


给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和并同样以字符串形式返回。


你不能使用任何內建的用于处理大整数的库(比如 BigInteger), 也不能直接将输入的字符串转换为整数形式。


1b9f6f3e0b694d0f824cecbbab16cf3c.png

思路:这道题主要考察的就是竖式相加,我们可以从字符串的末尾依次往前相加,并保存进位信息。那如何将这个过程转换成代码呢?先定义两个变量end1和end2,并初始化为size - 1,如何利用 while 循环从后往前遍历字符串。当end1和end2都小于0时,while 循环结束。在while 循环里,定义三个变量val1、val2和ret,ret等于val1 + val2 + carry,其中carry为进位信息,其值为ret / 10。如果end小于0,则val的值为0。现在我们已经得到了相加的结果和进位信息了,就可以将数据插入到字符串。插入有两种方式,可以头插,也可以尾插。如果采用头插,效率会比较低,因为需要挪动数据。如果采用尾插,循环结束后需要将字符串逆置一下。


class Solution 
{
public:
    string addStrings(string num1, string num2) 
    {
        int end1 = num1.size() - 1, end2 = num2.size() - 1;
        int carry = 0;
        string retStr;
        retStr.reserve(max(num1.size(), num2.size()) + 1);
        while(end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 >= 0 ? num1[end1] - '0' : 0;
            int val2 = end2 >= 0 ? num2[end2] - '0' : 0;
            int ret = val1 + val2 + carry;
            carry = ret / 10;
            ret %= 10;
            retStr.insert(0, 1, '0' + ret);
            --end1;
            --end2;
        }
    // 处理进位信息
        if(carry == 1)
            retStr.insert(0, 1, '1');
        return retStr;
    }
};

563d94857503431b88911c5be1915945.png


class Solution 
{
public:
    string addStrings(string num1, string num2) 
    {
        int end1 = num1.size() - 1, end2 = num2.size() - 1;
        int carry = 0;
        string retStr;
        retStr.reserve(max(num1.size(), num2.size()) + 1);
        while(end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 >= 0 ? num1[end1] - '0' : 0;
            int val2 = end2 >= 0 ? num2[end2] - '0' : 0;
            int ret = val1 + val2 + carry;
            carry = ret / 10;
            ret %= 10;
            retStr += '0' + ret;
            --end1;
            --end2;
        }
    // 处理进位信息
        if(carry == 1)
            retStr += '1';
        // 逆置字符串
        reverse(retStr.begin(), retStr.end());
        return retStr;
    }
};


8b2d8fdda9054aceae1b44bc38df76a5.png


👉字符串相乘👈


给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。


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

de89da4ab8d840c98424d6255e22500c.png


思路:首先将补零,将 num2 的每位数字和 num1 相乘的结果存到 ret1 里,再将 ret1 逆置就能得到 num2 的低位到高位与 num1 相乘的结果,最后将 ret1 加到结果 ret 上,ret 就是最终相乘的结果了。


2b0e363f55484d65bec01ad51012a55d.png


class Solution 
{
public:
    string addStrings(string num1, string num2) 
    {
        int end1 = num1.size() - 1, end2 = num2.size() - 1;
        int carry = 0;
        string retStr;
        retStr.reserve(max(num1.size(), num2.size()) + 1);
        while(end1 >= 0 || end2 >= 0)
        {
            int val1 = end1 >= 0 ? num1[end1] - '0' : 0;
            int val2 = end2 >= 0 ? num2[end2] - '0' : 0;
            int ret = val1 + val2 + carry;
            carry = ret / 10;
            ret %= 10;
            retStr += '0' + ret;
            --end1;
            --end2;
        }
        if(carry == 1)
            retStr += '1';
        reverse(retStr.begin(), retStr.end());
        return retStr;
    }
    string multiply(string num1, string num2) 
    {
        // 思路:首先将补零,将num2的每位数字和num1相乘的结果存到ret1里
        // 再将ret1逆置就能得到num2的个位、十位和百位与num1相乘的结果
        // 再将ret1加到结果ret上,ret就是最终相乘的结果了
        string ret("0");
        if(num1[0] == '0' || num2[0] == '0')
        {
            return ret;
        }
        int size1 = (int)num1.size();
        int size2 = (int)num2.size();
        for(int i = size2 - 1; i >=  0; i--)
        {
            string ret1;
            for(int j = 0; j < size2 - 1 - i; j++)
            {
                ret1.append(1, '0');
            }
            int carry = 0;
            for(int j = size1 - 1; j >= 0; j--)
            {
                int val1 = num1[j] - '0';
                int val2 = num2[i] - '0';
                int ret2 = val1 * val2 + carry;
                carry = ret2 / 10;
                ret1.append(1, '0' + ret2 % 10);
            }
            if(carry > 0)
            {
                ret1.append(1, '0' + carry);
            }
            reverse(ret1.begin(), ret1.end());
            ret = addStrings(ret, ret1);
        }
        return ret;
    }
};

c0cdf31abf274bfeb2f37ce553035bfb.png

👉反转字符串中的单词 III👈


给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

2d6bd3122f2d4cb59828d0376c4b07f6.png



思路:定义两个变量pos和prevpos,pos的初始值为第一个空格所在的位置,prevpos的初始值为0。当pos != string::npos时,进入 while 循环,将prevpos到pos之间的字符逆置,逆置之后,prevpos = pos + 1,pos等于下一个空格的位置;while 循环结束,将prevpos到s.size()-1之间的字符逆置,然后字符串的单词都逆置过来了。


class Solution 
{
public:
  // 逆置算法
    void reverse(string& s, size_t begin, size_t end)
    {
        while(begin < end)
        {
            swap(s[begin++], s[end--]);        
        }
    }
    string reverseWords(string s) 
    {
        size_t pos = s.find(' ', 0);
        size_t prevpos = 0;
        while(pos != string::npos)
        {
            reverse(s, prevpos, pos - 1);
            prevpos = pos + 1;
            pos = s.find(' ', pos + 1);
        }
        reverse(s, prevpos, s.size() - 1);
        return s;
    }
};


cf81cd1fd7974f05a1106367ca74ed7e.png


👉反转字符串 II👈


给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。

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

e5c4e66c3fad43ff879cee8798f7b8fa.png



思路:先定义一个逆置算法的函数,然后判断剩余的字符有多少,然后进行相应的操作就行了。


class Solution 
{
public:
  //翻转start到end区间的字符串
  void Reverse(string &s, int start, int end)
  {
    char tmp;
    while(start < end)
    {
      tmp = s[start];
      s[start] = s[end];
      s[end] = tmp;
      start++;
      end--;
    }
  }
  string reverseStr(string s, int k) 
  {
    int len = s.size();
    for(int i = 0; i < len; i += 2 * k)
    {
        // 剩余字符大于k个
        if(i + k - 1 < len)
            Reverse(s, i, i + k - 1);
        else  // 剩余字符小于或等于k个
            Reverse(s, i, len - 1);
    }
    return s;
  }
};


d2e43293241a4838aad7e347e23b7ae5.png


👉总结👈


好久没有写过刷题博客了,上次写的时候还是在上次。希望大家能够喜欢,那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️






相关文章
|
3月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
78 0
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
141 0
java基础(13)String类
|
6月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
145 11
|
6月前
|
Java
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
150 9
|
6月前
|
存储 JavaScript Java
课时44:String类对象两种实例化方式比较
本次课程的主要讨论了两种处理模式在Java程序中的应用,直接赋值和构造方法实例化。此外,还讨论了字符串池的概念,指出在Java程序的底层,DOM提供了专门的字符串池,用于存储和查找字符串。 1.直接赋值的对象化模式 2.字符串池的概念 3.构造方法实例化
|
10月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
302 2
|
11月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
224 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
12月前
|
安全 Java
String类-知识回顾①
这篇文章回顾了Java中String类的相关知识点,包括`==`操作符和`equals()`方法的区别、String类对象的不可变性及其好处、String常量池的概念,以及String对象的加法操作。文章通过代码示例详细解释了这些概念,并探讨了使用String常量池时的一些行为。
String类-知识回顾①
|
11月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
295 2
|
11月前
|
数据可视化 Java
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
167 4