【基础算法总结】字符串篇

devtools/2024/10/18 9:23:18/

目录

  • 一,算法简介
  • 二,算法原理和代码实现
    • 14.最长公共前缀
    • 5.最长回文子串
    • 67.二进制求和
    • 43.字符串相乘
  • 三,算法总结

一,算法简介

字符串 string 是一种数据结构,它一般和其他的算法结合在一起操作,比如和模拟,高精度加减,双指针,动态规划等算法结合,所以有关字符串类的题型是多种多样的。通过本篇文章挑选的一些题目来熟悉有关字符串接口的使用

二,算法原理和代码实现

14.最长公共前缀

在这里插入图片描述
在这里插入图片描述

算法原理:
这道题的本质是模拟,一般有以下两种模拟方法

解法1:两两字符串比较
可以封装一个函数用来找出两个字符串的最长公共前缀。固定一个字符串,用另一个字符串的每个字符和固定字符串的每个字符进行比较,保存相同的字符,直到其中一个字符串截止或是字符不相等,最后返回保存的字符串即可。
在这里插入图片描述
假设有 n 个字符串,每个字符串的平均长度为 m,则时间复杂度是 O(n*m)

代码实现:

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){string tmp = "";// 比较两两字符串的每个字符,返回相同的部分。直到一个结束或不相等int n = min(s1.size(), s2.size());for(int i = 0; i < n; i++)if(s1[i] == s2[i]) tmp += s1[i];else break;return tmp;}
};

解法2:统一比较
把每个字符串从头开始每个字符同时比较,保存相同字符(或是保存对应的下标,获取结果时直接截取),直到有一个字符串遍历结束或是字符不相等
在这里插入图片描述
假设有 n 个字符串,每个字符串的平均长度为 m,则时间复杂度也是 O(n*m)。

细节问题:

这里有一个选谁作为参考的问题:
我们可以选第一个字符串作为参考。第一层循环的结束条件用第一个字符串的长度,第二层循环比较字符是否相等时也用第一个字符串的每个字符作参考,如果某一个长度越界了或是字符不相同了就截取

代码实现:

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];}
};

5.最长回文子串

在这里插入图片描述

算法原理:

解法:中心拓展算法
中心拓展算法的本质是使用双指针进行暴力枚举,只不过是根据回文子串的特性枚举的
算法流程:
(1) 遍历字符串,依次固定每一个字符作为中心 i
(2) 从中心点开始,使用双指针 left 和 right,当两者不越界并且两个字符相等时,同时向两边扩展

细节问题:

奇数长度和偶数长度都需要考虑
先定义变量 begin 为回文串的起始长度,len 为回文串的长度
(1) 奇数长度的扩展
定义 left 和 right 作为回文子串边界的下一个位置,left = right = i,若 left 和 right 不越界,且s[left] == s[right],则 left–,right++
当跳出循环,且left 和 right之间的长度 > len 时,就要更新 begin 和 len
(2) 偶数长度的扩展
让 left = i,right = i + 1,其他的与奇数长度的扩展一致

代码实现:

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

67.二进制求和

在这里插入图片描述

算法原理:

本题是一个二进制的高精度加法模拟题,本质是模拟加法的列竖式运算。
在这里插入图片描述

代码实现:

class Solution 
{
public:string addBinary(string a, string b) {int i = a.size() - 1, j = b.size() - 1, t = 0;string ret = "";while(i >= 0 || j >= 0 || t){if(i >= 0) t += (a[i--] - '0');if(j >= 0) t += (b[j--] - '0');ret += (t % 2 + '0');t /= 2;}reverse(ret.begin(), ret.end());return ret;}
};

43.字符串相乘

在这里插入图片描述
在这里插入图片描述

算法原理:
本题是一道高精度乘法的模拟题

解法1:模拟竖式乘法运算
先把两个字符串逆序,固定一个字符,遍历另一个与它相乘。思路很好想,但是代码不好写,有很多细节
细节问题:
(1) 高位相乘的时候要补"0"
(2) 处理前导0
在这里插入图片描述
(3) 注意最后结果的逆序

解法2:对解法1做优化,先无进位相乘再相加,最后处理进位
这个解法的核心是要借助一个辅助数组。假设两个字符串的长度是m,n,则创建一个大小为 m+n-1的数组,再用两层for循环模拟竖式乘法计算出每一个相乘的值,把每个值都扔进数组中的对应位置,并且把每次相乘的值和原来对应位置的值相加,最后再处理进位

图解1如下

在这里插入图片描述
在这里插入图片描述

图解2如下:
在这里插入图片描述

代码实现:

class Solution 
{
public:string multiply(string num1, string num2) {// 准备工作int n = num1.size(), m = num2.size();vector<int> add(n+m-1);reverse(num1.begin(), num1.end());reverse(num2.begin(), num2.end());// 无进位相乘再相加,放入数组的对应位置for(int i = 0; i < n; i++)for(int j = 0; j < m; j++)add[i+j] += ((num1[i] - '0') * (num2[j] - '0'));// 处理进位,把数组里的值相加int t = 0, i = 0;string ret = "";while(i < n+m-1 || t){if(i < n+m-1) t += add[i++];ret += to_string(t % 10);t /= 10;}// 处理前导0reverse(ret.begin(), ret.end());if(ret[0] == '0') return "0";return ret;}
};

三,算法总结

字符串类型的算法题型是多种多样的,并且也可以使用多种字符串函数接口了解决问题。


http://www.ppmy.cn/devtools/124948.html

相关文章

Winform和WPF的技术对比

WinForms&#xff08;Windows Forms&#xff09;和WPF&#xff08;Windows Presentation Foundation&#xff09;是用于创建桌面应用程序的两种技术。尽管两者都可以用于开发功能强大的Windows应用程序&#xff0c;但它们的设计理念、功能和开发体验都有显著区别。在本文中&…

GitHub简介与安装使用入门教程

1、Git与GitHub的简介 Git是目前世界上最先进的分布式控制系统&#xff0c;它允许开发者跟踪和管理源代码的改动历史记录等&#xff0c;可以将你的代码恢复到某一个版本&#xff0c;支持多人协作开发。它的核心功能包括版本控制、分支管理、合并和冲突解决等&#xff0c;其操作…

根据Vue对比来深入学习React 上 函数组件 jsx 事件绑定 响应式数据 条件绑定 列表渲染 表单绑定

文章目录 React项目创建React核心库介绍React组件jsx编写jsx代码的本质jsx里面渲染不同内容 事件绑定事件绑定其他操作特别注意 响应式数据setState 的特性 条件渲染列表循环表单绑定总结 React项目创建 react官网提供了很多生产级的React框架 比如next.js&#xff0c;不过你还…

Python知识点:基于Python技术,如何使用OpenCV进行道路标志识别

开篇&#xff0c;先说一个好消息&#xff0c;截止到2025年1月1日前&#xff0c;翻到文末找到我&#xff0c;赠送定制版的开题报告和任务书&#xff0c;先到先得&#xff01;过期不候&#xff01; 使用OpenCV进行道路标志识别的Python技术详解 道路标志识别是智能交通系统中的应…

【动手学深度学习】6.4 多输入多输出通道

彩色图像具有标准的RBG通道来代表红绿蓝&#xff0c;但是到目前位置我们仅展示了单个输入和单个通道的简化例子。这使得我们可以将输入&#xff0c;卷积核和输出看作二维张量而当我们添加通道时&#xff0c;输入和隐藏表示都变成了三维张量。例如每个RGB输入图像都具有 3 h …

【云从】三、计算机网络基础

文章目录 1、网络2、网络通信2.1 IP地址2.2 子网掩码2.3 网关2.4 私有地址和公有地址2.5 NAT网络地址转换 3、网络架构及设备 1、网络 网络&#xff0c;即通过通信线路&#xff08;如光纤、网线&#xff09;和通信设备&#xff08;如路由器、光猫&#xff09;&#xff0c;将各…

对偶范数(Dual Norm)

文章目录 1. 对偶范数的定义2. 常见范数和对偶范数的关系3. 直观理解4. 示例5. 应用场景6.总结 对偶范数&#xff08;Dual Norm&#xff09; 是在泛函分析和凸优化中非常重要的概念。它用于衡量向量和线性函数之间的关系&#xff0c;尤其是在优化问题和范数的几何理解中非常有用…

Rider 编译 UE5 项目 MSBuild 报错解决

报错信息&#xff1a; CONSOLE: Use build tool: D:\Work\Microsoft Visual Studio\MSBuild\Current\Bin\amd64\MSBuild.exe Microsoft.NET.Sdk.ImportWorkloads.props(14,3): Error : 无法解析 SDK“Microsoft.NET.SDK.WorkloadAutoImportPropsLocator”。下面的探测消息中正…