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;
    }
};
相关推荐
StickToForever31 分钟前
第4章 信息系统架构(五)
经验分享·笔记·学习·职场和发展
计算机小白一个2 小时前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^3 小时前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
欧了1115 小时前
洛谷P9240 [蓝桥杯 2023 省 B] 冶炼金属
职场和发展·蓝桥杯·洛谷·蓝桥杯大学b组c语言
大数据追光猿5 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!5 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉5 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生5 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴5 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing5 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode