LeetCode刷题 -- 字符串

目录

最长公共前缀

题目链接

题目解析

只需找出字符串中的公共的最长字符串即可

算法原理

1.法一:两两字符串比较,比较完和下一个字符串比较,找出所有字符串中共同的子串
2.法二:统一比较,固定i不变,逐一比较每行的第i个元素,存在不同就比较完成
3.法三:先算出最小字符串的长度,(统一比较)然后逐一比较每个字符串中字符是否相同

代码

cpp 复制代码
// 解法一
// N:字符串的个数 M:字符串的平均长度
// 时间复杂度:O(N*M)
// 空间复杂度:O(1)
class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
       // 2. 统一比较
       for(int i = 0;i < strs[0].size();++i)// 列
       {
           char ch = strs[0][i];
           for(int j = 1;j < strs.size();++j)// 行
           {
             if(i == strs[j].size() || ch != strs[j][i]) 
             return strs[0].substr(0,i);
           }
       }    
       return strs[0];
    }
};
// 解法二
// N:字符串的个数 M:字符串的平均长度
// 时间复杂度:O(N*M)
// 空间复杂度:O(1)
class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
       // 2. 统一比较
       for(int i = 0;i < strs[0].size();++i)// 列
       {
           char ch = strs[0][i];
           for(int j = 1;j < strs.size();++j)// 行
           {
             if(i == strs[j].size() || ch != strs[j][i]) 
             return strs[0].substr(0,i);
           }
       }    
       return strs[0];
    }
};
// 解法三
// N:字符串的个数 M:字符串的平均长度
// 时间复杂度:O(N*M)
// 空间复杂度:O(M)
class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs)
    {
        // 3. 取出最小字串的长度
        //    然后逐一比较各位字符
        if(strs.size() == 1)
        return strs[0];
        string ret;
        int m = 200;
        for(int i = 0;i < strs.size();i++)
        {
            int k = strs[i].size();
            m = min(m,k);
        }    
        // 列
        for(int i = 0;i < m;i++)
        {
            // 行
            int flag = 1;
            char t = 0;
            for(int j = 0;j < strs.size()-1;++j)
            {
                t = strs[j][i];
                if(strs[j][i] != strs[j+1][i])
                {
                    flag = 0;
                    break;
                }
            }
            if(flag == 1)
            {
                ret.push_back(t);
            }
            else break;
        }
        return ret;
    }
};

最长回文子串

题目链接

题目解析

找出字符串的最长回文子串 bab aba 子串

算法原理

解法一:暴力枚举,每次枚举一个字符串,用O(N^2),再判断是否是回文串用O(N),三层循环,O(N^3),固定i = 0,每次从j = i开始枚举字符串,再判断字符串
解法二:从中间开始向两边扩展,固定一个中点,i遍历n次,第一种情况left和right都从i位置向两边扩展(字符串是奇数个字符),第二种情况,left从i位置,right从i+1位置向两边扩展(字符串是偶数个字符),这样字符串是奇数和偶数的情况都覆盖到了,两种情况遍历字符串2*n次,时间复杂度是O(N*N)

代码

cpp 复制代码
class Solution 
{
public:
    string longestPalindrome(string s) 
    {
       int n = s.size();
       int begin = 0,len = 0;// 起始位置和长度
       // 时间复杂度:O(N^2) -> n * 2n
       // 空间复杂度:O(1)
       for(int i = 0;i < n;++i)
       {
         //先做奇数次扩展
         int left = i,right = i;
         while(left >= 0 && right < n && s[left] == s[right]) 
         {
            left--;
            right++;
         }
         if(right - left - 1 > len)
         {
            begin = left + 1;
            len = right - left - 1;
         }
         // 再做偶数次扩展
         left = i,right = i + 1;
         while(left >= 0&&right < n&&s[left] == s[right])
         {
           left--;
           right++;
         }
         if(right - left - 1 > len)
         {
            begin = left + 1;
            len = right - left - 1;
         }
       }
       return s.substr(begin,len);
    }
};

二进制求和

题目链接

题目解析

按照二进制的加法求和

算法原理

高精度算法
用t来记录两个字符串各个位上的加和,t%2是相加之后的值,t/2是进位,t再和下一次两个字符串各位上的值相加如此往复即可得到答案,可以自己模拟一遍

代码

cpp 复制代码
class Solution 
{
public:
    string addBinary(string a, string b) 
    {
        // 高精度加法
        // 时间复杂度:O(ab字符串长的那个)
        // 空间复杂度:O(ab字符串长的那个)
        string ret;
        int t = 0;
        int cur1 = a.size() - 1,cur2 = b.size() - 1;
        while(cur1 >= 0|| cur2 >= 0|| t)
        {
           if(cur1 >= 0) t += a[cur1--] - '0';
           if(cur2 >= 0) t += b[cur2--] - '0';
           ret += t % 2 + '0';
           t /= 2;
        }
        reverse(ret.begin(),ret.end());
        return ret;
    }
};

字符串相乘

题目链接

题目解析

两个字符串相乘

算法原理

法一:模拟,固定一个字符和其他字符串相乘,两个for循环,注意要先逆置后计算,先要加入前导零,<高位相乘的时候要补上零>,表示逆序,加完后就是逆序的结果了 <最后处理前导零并且要逆序回来>
法二:1. 无进位相乘然后相加(注意是逆序的)并且最后乘出来的数组大小是m+n-1(按下标相加的大小来看)

  1. 处理进位 (t表示数组中的值,t%10 -> 该位的数值 ,t / 10 ->进位)
  2. 处理前导零
  3. 逆序

代码

cpp 复制代码
class Solution 
{
public:
    string multiply(string num1, string num2) 
    {
        // 高精度乘法
        // 先无进位相乘再相加,处理进位,和前导零
        //  1. 准备工作
        int n = num1.size(),m = num2.size();
        // 逆置字符串
        reverse(num1.begin(),num1.end());
        reverse(num2.begin(),num2.end());
        vector<int> tmp(n+m-1);
        
        // 2.无进位相乘再相加
        for(int i = 0;i < n;++i)
         for(int j = 0;j < m;++j)
         tmp[i + j] += (num1[i] - '0') * (num2[j] - '0');

         // 3.处理进位
        string ret;
        int cur1 = 0,t = 0;// cur1 下标 t 进位
        while(cur1 < m+n-1 || t != 0)
        {
            if(cur1 < m + n - 1) t += tmp[cur1++];
            ret += t % 10 + '0';// 该位的数值
            t /= 10;// 进位
        }

        // 4. 处理前导零 逆置后零在后面 0 02 -> 20
        //while(ret.size() > 1 && ret[ret.size()-1] == '0')  ret.pop_back();
        // ret.back()
        while(ret.size() > 1 && ret.back() == '0') ret.pop_back();
        reverse(ret.begin(),ret.end());
        return ret;
    }
};
相关推荐
dorabighead几秒前
小哆啦解题记:加油站的奇幻冒险
数据结构·算法
Ritsu栗子16 分钟前
代码随想录算法训练营day35
c++·算法
MrZhangBaby18 分钟前
SQL-leetcode—1158. 市场分析 I
java·sql·leetcode
好一点,更好一点26 分钟前
systemC示例
开发语言·c++·算法
卷卷的小趴菜学编程1 小时前
c++之List容器的模拟实现
服务器·c语言·开发语言·数据结构·c++·算法·list
林开落L1 小时前
模拟算法习题篇
算法
玉蜉蝣1 小时前
PAT甲级-1014 Waiting in Line
c++·算法·队列·pat甲·银行排队问题
我真不会起名字啊1 小时前
“深入浅出”系列之算法篇:(2)openCV、openMV、openGL
算法
南宫生1 小时前
力扣动态规划-7【算法学习day.101】
java·数据结构·算法·leetcode·动态规划
spssau2 小时前
2025美赛倒计时,数学建模五类模型40+常用算法及算法手册汇总
算法·数学建模·数据分析·spssau