力扣算法题:字符串(最长公共前缀|最长回文子串)

上篇文章:力扣C++算法:哈希表(存在重复元素|存在重复元素II|字母异位词分组)

目录

1.最长公共前缀

算法原理

解法一:两两比较

解法二:统一比较

2.最长回文子串

算法原理

解法:中心扩展算法


1.最长公共前缀

https://leetcode.cn/problems/longest-common-prefix/description/

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""

算法原理

解法一:两两比较

如下图所示,各个字符串依次两两比较,最终返回相同的部分,边界条件处理:当比较时遇到空字符,则比较结束。

cpp 复制代码
class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        string ret = strs[0];
        for(int i = 1; i < strs.size(); i++)
        {
            ret = findCommon(ret, strs[i]);
        }
        return ret;
    }

    string findCommon(string& s1, string& s2)
    {
        int i = 0;
        while(i < min(s1.size(), s2.size()) && s1[i] == s2[i]) i++;
        return s1.substr(0, i);
    }
};

解法二:统一比较

以strs[0]为基准,将所有字符串进行统一比较,如下图所示:

cpp 复制代码
class Solution 
{
public:
    string longestCommonPrefix(vector<string>& strs) 
    {
        for(int i = 0; i < strs[0].size(); i++)
        {
            char tmp = strs[0][i];
            for(int j = 1; j < strs.size(); j++)
            {
                if(i == strs[j].size() || tmp != strs[j][i])
                    return strs[0].substr(0, i);
            }
        }
        return strs[0];
    }
};

2.最长回文子串

https://leetcode.cn/problems/longest-palindromic-substring/description/

给你一个字符串 s,找到 s 中最长的 回文 子串。

算法原理

解法:中心扩展算法

暴力枚举策略:固定i,依次移动j,进行一一对比。

我们在此基础上做出优化

定义一个中点,将其指针向前和向后进行移动,依次对比字符

并且考虑奇数长度与偶数长度之间的不同

cpp 复制代码
class Solution {
public:
    string longestPalindrome(string s) {
        int begin = 0, len = 0, n = s.size();
        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);
    }
};

本章完。

相关推荐
承渊政道2 小时前
【递归、搜索与回溯算法】(穷举vs暴搜vs深搜vs回溯vs剪枝:一文讲清概念与用法)
数据结构·c++·算法·决策树·深度优先·剪枝·宽度优先
承渊政道2 小时前
【递归、搜索与回溯算法】(综合练习:一网打尽常见题型分类总结与方法归纳)
c++·算法·决策树·分类·深度优先·哈希算法·宽度优先
我不是懒洋洋2 小时前
【数据结构】栈和链表基本方法的实现
c语言·开发语言·数据结构·c++·链表·青少年编程·ecmascript
邪修king2 小时前
C++ vector 超全攻略:核心知识点、STL 生态联系与避坑指南
c语言·c++·面试
小江的记录本2 小时前
【网络安全】《网络安全与数据安全核心知识体系》(包括数据脱敏、数据加密、隐私合规、等保2.0)
java·网络·后端·python·算法·安全·web安全
SimpleLearingAI2 小时前
ROPE:大模型必学操作
人工智能·算法
zore_c2 小时前
【C++】C++类和对象实现日期类项目——时间计算器!!!
java·c语言·数据库·c++·笔记·算法·排序算法
草莓熊Lotso2 小时前
Linux 线程同步与互斥(二):线程同步从条件变量到生产者消费者模型全解,原理 + 源码彻底吃透
linux·运维·服务器·c语言·开发语言·数据库·c++
人道领域2 小时前
【LeetCode刷题日记】:344,541-字符串反转字符串反转技巧:双指针原地交换法
算法·leetcode·面试