《算法题讲解指南:优选算法-字符串》--61.最长公共前缀,62.最长回文子串,63.二进制求和,64.字符串相乘

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

61.最长公共前缀

题目链接:

题目描述:

题目示例:

解法一(两两比较):

算法思路:

解法二(统一比较):

算法思路:

C++算法代码(解法一:两两比较):

C++算法代码(解法二:统一比较):

算法总结及流程解析:

62.最长回文子串

题目链接:

题目描述:

题目示例:

解法(中心扩散):

算法思路:

C++算法代码:

算法总结及流程解析:

63.二进制求和

题目链接:

题目描述:

题目示例:

3.解法(模拟十进制的大数相加的过程):

算法思路:

C++算法代码:

64.字符串相乘

题目链接:

题目描述:

题目示例:

解法(无进位相乘然后相加,最后处理进位):

算法思路:

C++算法代码(解法一:"模拟"列竖式运算):

C++算法代码(解法二:先无进位相乘再相加,最后处理进位):

算法总结及流程解析:

结束语


61.最长公共前缀

题目链接:

14. 最长公共前缀 - 力扣(LeetCode)

题目描述:

题目示例:

解法一(两两比较):

算法思路:

我们可以先找出前两个的最长公共前缀,然后拿这个最长公共前缀依次与后面的字符串比较,这样就可以找出所有字符串的最长公共前缀。

解法二(统一比较):

算法思路:

题目要求多个字符串的公共前缀,我们可以逐位比较这些字符串,哪一位出现了不同,就在哪一位截止。

C++算法代码(解法一:两两比较):

cpp 复制代码
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        //解法一:字符串两两比较
        string ret = strs[0];
        for(int i = 1; i < strs.size(); i++)
        {
            int index = 0;
            while(index < min(ret.size(), strs[i].size()) && ret[index] == strs[i][index])
            {
                index++;
            }
            ret = strs[i].substr(0, index);
        }
        return ret;
    }
};

C++算法代码(解法二:统一比较):

cpp 复制代码
class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        //解法二:统一比较
        string ret;
        int index;
        for(int i = 0; i < strs[0].size(); i++)
        {
            index = i;
            for(int j = 1; j < strs.size(); j++)
            {
                if(index >= strs[j].size() || strs[0][index] != strs[j][index])
                {
                    ret = strs[0].substr(0, index);
                    return ret;
                }
            }
        }
        ret = strs[0].substr(0, index + 1);
        return ret;
    }
};

算法总结及流程解析:

62.最长回文子串

题目链接:

5. 最长回文子串 - 力扣(LeetCode)

题目描述:

题目示例:

解法(中心扩散):

算法思路:

枚举每一个可能的子串非常费时,有没有比较简单一点的方法呢?

对于一个子串而言,如果它是回文串,并且长度大于2,那么将它首尾的两个字母去除之后,它仍然是个回文串。如此这样去除,一直除到长度小于等于2时呢?长度为1 的,自身与自身就构成回文;而长度为2的,就要判断这两个字符是否相等了。

从这个性质可以反推出来,从回文串的中心开始,往左读和往右读也是一样的。那么,是否可以枚举回文串的中心呢?

从中心向两边扩展,如果两边的字母相同,我们就可以继续扩展;如果不同,我们就停止扩展。这样只需要一层for循环,我们就可以完成先前两层for循环的工作量。

C++算法代码:

cpp 复制代码
class Solution {
public:
    string longestPalindrome(string s) 
    {
        int left = 0;
        int right = 0;
        int len = 0;
        int begin = 0;
        string ret;
        //中心扩展算法
        for(int i = 0; i < s.size(); i++)
        {
            left = right = i;
            //奇数长度的扩展
            while(left >= 0 && right < s.size() && s[left] == s[right])
            {
                left--;
                right++;
            }
            if(len < right - left - 1)
            {
                begin = left + 1;
                len = right - left - 1;
            }
            //偶数长度的扩展
            if(i >= 1 && s[i] == s[i - 1])
            {
                left = i - 1;
                right = i;
                while(left >= 0 && right < s.size() && s[left] == s[right])
                {
                    left--;
                    right++;
                }
                if(len < right - left - 1)
                {
                    begin = left + 1;
                    len = right - left - 1;
                }
            }
        }    
        ret = s.substr(begin, len);
        return ret;
    }
};

算法总结及流程解析:

63.二进制求和

题目链接:

67. 二进制求和 - 力扣(LeetCode)

题目描述:

题目示例:

3.解法(模拟十进制的大数相加的过程):

算法思路:

模拟十进制中我们列竖式计算两个数之和的过程。但是这里是二进制的求和,我们不是逢十进一,而是逢二进一。

C++算法代码:

cpp 复制代码
class Solution {
public:
    string addBinary(string a, string b) 
    {
        int ai = a.size() - 1;
        int bi = b.size() - 1;
        string ret;
        int rem = 0;
        while(ai >= 0 || bi >= 0 || rem)
        {
            if(ai >= 0)
            {
                rem += a[ai] - '0';
            }
            if( bi >= 0)
            {
                rem += b[bi] - '0';
            }
            ret += to_string(rem % 2);
            rem /= 2;
            ai--;
            bi--;
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

64.字符串相乘

题目链接:

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

题目描述:

题目示例:

解法(无进位相乘然后相加,最后处理进位):

算法思路:

整体思路就是模拟我们小学列竖式计算两个数相乘的过程。但是为了我们书写代码的方便性,我们选择一种优化版本的,就是在计算两数相乘的时候,先不考虑进位,等到所有结果计算完毕之后,再去考虑进位。如下图:

C++算法代码(解法一:"模拟"列竖式运算):

cpp 复制代码
class Solution {
public:
    string addBinary(string a, string b) 
    {
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        int ai = a.size() - 1;
        int bi = b.size() - 1;
        string ret;
        int rem = 0;
        while(ai >= 0 || bi >= 0 || rem)
        {
            if(ai >= 0)
            {
                rem += a[ai] - '0';
            }
            if( bi >= 0)
            {
                rem += b[bi] - '0';
            }
            ret += to_string(rem % 10);
            rem /= 10;
            ai--;
            bi--;
        }
        return ret;
    }

    string multiply(string num1, string num2) 
    {
        //解法一:"模拟"列竖式运算
        if(num1 == "0" || num2 == "0")
        {
            return "0";
        }
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());
        string ret = "0";
        for(int i = 0; i < num2.size(); i++)
        {
            int rem = 0;
            string tmp;
            int T = i;
            while(T--)
            {
                tmp += '0';
            }
            int j = 0;
            while(j < num1.size() || rem)
            {
                if(j < num1.size())
                {
                    rem += ((num2[i] - '0') * (num1[j] - '0'));
                }
                tmp += to_string(rem % 10);
                rem /= 10;
                j++;
            }
            ret = addBinary(tmp, ret);
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

C++算法代码(解法二:先无进位相乘再相加,最后处理进位):

cpp 复制代码
class Solution {
public:
    string multiply(string num1, string num2) 
    {
        //解法二:先无进位相乘再相加,最后处理进位
        if(num1 == "0" || num2 == "0")
        {
            return "0";
        }
        //1、准备工作
        reverse(num1.begin(), num1.end());
        reverse(num2.begin(), num2.end());
        int m = num1.size();
        int n = num2.size();
        vector<int> tmp(m + n - 1);

        //2、先无进位相乘再相加
        for(int i = 0; i < num2.size(); i++)
        {
            for(int j = 0; j < num1.size(); j++)
            {
                tmp[i + j] += ( num1[j] - '0') * (num2[i] - '0');
            }
        }

        //3、最后处理进位
        string ret;
        int rem = 0;
        int i = 0;
        while(i < tmp.size() || rem)
        {
            if(i < tmp.size())
            {
                rem += tmp[i];
            }
            ret += to_string(rem % 10);
            rem /= 10;
            i++;
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

算法总结及流程解析:

结束语

到此,61.最长公共前缀,62.最长回文子串,63.二进制求和,64.字符串相乘 这四道算法题就讲解完了。**最长公共前缀的两种解法(两两比较和统一比较); 最长回文子串的中心扩散法;二进制求和的模拟竖式加法;字符串相乘的两种解法(模拟竖式乘法和无进位相乘再处理进位)。每种解法都提供了C++代码实现和思路解析,涵盖字符串处理中的常见问题,包括前缀匹配、回文检测、二进制运算和大数相乘等典型场景。**希望大家能有所收获!

相关推荐
做怪小疯子2 小时前
LeetCode刷题——15.动态规划模式
算法·leetcode·动态规划
如竟没有火炬2 小时前
搜索二维矩阵
数据结构·python·算法·leetcode·矩阵
chh5632 小时前
从零开始学C++--类和对象
java·开发语言·c++·学习·算法
森屿~~2 小时前
PlatEMO 深度实战解析——从底层架构到 CMOPs 与 MMO 算法魔改
算法
郝学胜-神的一滴2 小时前
自动微分实战:梯度下降的迭代实现与梯度清零核心解析
人工智能·pytorch·python·深度学习·算法·机器学习
daad7772 小时前
std::vector insert
算法
炽烈小老头2 小时前
【每天学习一点算法 2026/04/07】快乐数
学习·算法
计算机安禾2 小时前
【数据结构与算法】第31篇:排序概述与插入排序
c语言·开发语言·数据结构·学习·算法·重构·排序算法
xyx-3v2 小时前
C++构造函数、析构函数与拷贝控制深度解析
开发语言·c++