【优选算法】字符串

server/2024/12/15 8:51:27/

在这里插入图片描述

目录

  • 一、[最长公共前缀](https://leetcode.cn/problems/longest-common-prefix/description/)
  • 二、[最长回文子串](https://leetcode.cn/problems/longest-palindromic-substring/description/)
  • 三、[二进制求和](https://leetcode.cn/problems/add-binary/description/)
  • 四、[字符串相乘](https://leetcode.cn/problems/multiply-strings/description/)
  • 结尾

一、最长公共前缀

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

思路讲解
本题需要找到所有字符串的公共前缀,那么我们可以先找到两个字符串的公共前缀,再跟其他字符串得到新的公共前缀,重复这个操作,最终找到所有字符串的公共前缀。
在这里插入图片描述
除了比较两个字符串的方式,还可以同时比较所有字符串,我们可以先找到最短字符串并记录它的长度,我们使用这个长度用来遍历所有字符串,就不会出现越界的情况,每遍历1位,就判断当前位上所有字符串上的字符是否相同,相同则向后遍历,不相同或是遍历完后则返回前面部分。

在这里插入图片描述

编写代码

class Solution {
public:string longestCommonPrefix(vector<string>& strs) {string ans;int strsLen = strs.size();int MinStrLen = 201;   // 记录最短for(int i = 0 ; i < strsLen ;i++){int strLen = strs[i].size();MinStrLen = MinStrLen <  strLen ? MinStrLen : strLen;}for(int i = 0 ; i < MinStrLen ;i++){char ch = strs[0][i];for(int j = 0 ; j < strsLen ; j++){if(ch != strs[j][i])return ans;}ans += ch;}return ans;}
};

二、最长回文子串

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

思路讲解
本题的暴力解法是找出字符串的所有子字符串,判断这些子字符串中有哪些字符串是符合回文规则的,并找到最长的一条返回,按照这个思路来讲,本题的时间复杂度将会达到O(n3),并不是一个很好的解法。

本题我们使用中心扩展算法来解决本题,首先定义一个中心点在数组的最左边,在定义两个变量来记录回文字符串的左右边界的下标,然后从中心点向两边延展,若两个位置的字符相同则继续向两边延展,当两个位置的字符不相同或是其中一边越界,与目前最长的回文字符串作比较,大于则更新新回文字符串的左右边界的下标,小于等于则不做处理,再将中心点向右移动,再重复上面的操作。
在这里插入图片描述

上面的操作只针对了回文字符串为奇数的情况,若为偶数的情况,则选最左边两个相邻的两个点作为中心点,然后从中心点向两边延展,重复上面的操作。
在这里插入图片描述

编写代码

class Solution {
public:string longestPalindrome(string s) {int sLen = s.size();int MaxLeft = 0 , MaxRight = 0;for(int i = 0 ; i < sLen ; i++){// 回文为奇数个的情况int left = i , right = i;// 当两个字母相同向两边延伸while((left >= 0 && right < sLen) && s[left] == s[right]){left--;right++;}// 不相同时,判断与之前最长回文串的长度作比较if(right - left - 2> MaxRight - MaxLeft){MaxLeft = left + 1;MaxRight = right - 1;}// 回文为偶数个的情况left = i , right = i + 1;// 当两个字母相同向两边延伸while(left >= 0 && right < sLen && s[left] == s[right]){left--;right++;}// 不相同或越界时,判断与之前最长回文串的长度作比较if(right - left - 2 > MaxRight - MaxLeft){MaxLeft = left + 1;MaxRight = right - 1;}}return s.substr(MaxLeft , MaxRight - MaxLeft + 1);}
};

三、二进制求和

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

思路讲解
本题的思路是将两个字符串逆转,然后将两个字符串就从低位开始相加,得到的字符串反转后得到答案。

在这里插入图片描述

编写代码

class Solution {
public:string addBinary(string a, string b) {reverse(a.begin(),a.end());reverse(b.begin(),b.end());string ans;int aLen = a.size() , bLen = b.size();int add = 0;  // 代表进位for(int i = 0 ; i < aLen || i < bLen || add; i++){int num1 = i < aLen ? a[i] - '0' : 0;int num2 = i < bLen ? b[i] - '0' : 0;int sum = num1 + num2 + add;add = sum / 2;ans += (sum % 2) + '0';}reverse(ans.begin(),ans.end());return ans;}
};

四、字符串相乘

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

思路讲解
解法一:“模拟”列竖式运算

将num1和num2逆转,定义一个字符串str来记录答案,定义一个字符串tmp记录num2中每一个数字乘num1得到的字符串,并将tmp与str相加,当得到的所有tmp都相加以后,需要注意的是这里我们将num1和num2逆转以后再计算的,所以这里的str是逆序的,所以再将str逆转就可以得到答案。

使用这个方法有三个细节点:

  1. 高位相乘时,需要补上"0"
  2. 处理前导0,当两个字符串中有一个位0就返回0
  3. 需要将得str逆转得到答案
    在这里插入图片描述

解法二:无进位相乘然后相加,最后处理进位
将num1和num2逆转,定义两个变量n,m分别记录num1和num2的长度,那么num1和num2相乘得到结果的长度必定为n+m-1,定义一个数组int tmp[n+m-1]记录结果中每一个位置的无进位相乘的结果,将num1中的每一位与num2中的每一位相乘,得到的结果放入到tmp中,放入tmp中位置的计算公式为num1当前数字下标与num2当前数字下标相加,当相乘完后,再处理数组tmp的进位,定义一个字符串ans来记录处理tmp得到的结果,需要注意的是这里我们将num1和num2逆转以后再计算的,所以这里的ans是逆序的,我们需要逆转ans才能得到最终的答案。

使用这个方法有三个细节点:

  1. 计算相乘时,加入到tmp位置的计算方式
  2. 处理前导0,当两个字符串中有一个位0就返回0
  3. 需要将得ans逆转得到答案
    在这里插入图片描述

编写代码

class Solution {
public:string multiply(string num1, string num2) {int numLen1 = num1.size();int numLen2 = num2.size();if((numLen1 == 1 && num1[0] == '0') || numLen2 == 1 && num2[0] == '0' )return "0";reverse(num1.begin(),num1.end());reverse(num2.begin(),num2.end());vector<int> v(numLen1 + numLen2 - 1);for(int i = 0 ; i < numLen1 ; i++){for(int j = 0 ; j < numLen2 ; j++){v[i+j] += (num1[i] - '0') * (num2[j] - '0');}}int add = 0;string ans;for(int i = 0 ; i < v.size() ; i++){int sum = v[i] + add;add = sum / 10;ans += to_string(sum % 10);}while(add){ans += to_string(add % 10);add /= 10;}reverse(ans.begin(),ans.end());return ans;}
};

结尾

如果有什么建议和疑问,或是有什么错误,大家可以在评论区中提出。
希望大家以后也能和我一起进步!!🌹🌹
如果这篇文章对你有用的话,希望大家给一个三连支持一下!!🌹🌹

在这里插入图片描述


http://www.ppmy.cn/server/150314.html

相关文章

一文讲清数据库的分库分表

想必大家在面试的时候都被问到过数据库的分库分表应该怎么做。 分库分表指的是是将大型数据库分割成多个小型数据库或表格的技术&#xff0c;旨在通过分散数据来提升性能、增加可扩展性和简化管理。随着数据量的增长&#xff0c;传统的单体数据库可能会遭遇性能瓶颈&#xff0…

画图,matlab,

clear;close all;clc;tic;dirOutput dir(*.dat); % 罗列所有后缀-1.dat的文件列表&#xff0c;罗列BDDATA的数据 filenames string({dirOutput.name}); % 提取文件名%% 丢包统计 FILENAMES [""]; LOSS_YTJ [ ]; LOSS_RAD [ ]; LOSS_ETH [ ]…

如何有效地规避空格的输入?

我发现你不管是使用C语言的gets函数还是使用c的getline函数都不能躲避空格&#xff0c;只能躲避回车&#xff0c;那么当我想规避空格的时候&#xff0c;我应该使用什么捏&#xff1f; 天选符号---->>>> "%s" <<<<------- 如果你只是来找一…

使用idea创建一个JAVA WEB项目

文章目录 1. javaweb项目简介2. 创建2.1 idea新建项目2.2 选择&#xff0c;命名2.3 打开2.4 选择tomcat运行2.5 结果 3. 总结 1. javaweb项目简介 JavaWeb项目是一种基于Java技术的Web应用程序&#xff0c;主要用于开发动态网页和Web服务。这种项目能够构建在Java技术栈之上&a…

航空航天总线协议分析ARINC429

ARINC429是商用飞机和运输机运用最广泛的总线之一&#xff0c;ARINC是美国航空无线电公司(Aeronautical Radio INC.)的缩写&#xff0c;ARINC429总线协议是美国航空电子工程委员会于1977年7月提出发表并获批准使用&#xff0c;它的规范全称是数字式信息传输系统(Digital Inform…

排队论、负载均衡和任务调度关系

目录 排队论、负载均衡和任务调度关系 一、排队论 二、负载均衡 三、任务调度 四、总结 排队论、负载均衡和任务调度关系 排队论为负载均衡和任务调度提供了数学理论和方法支持 排队论、负载均衡和任务调度是三个相关但不同的概念。以下是对这三个概念的详细解释和它们之…

软考高级 架构师 第六章 计算机系统其他基础知识

第六章其他计算机系统知识 1.计算机语言 计算机语言主要由一套指令构成&#xff0c;这种指令一般包含三大部分&#xff1a;表达式、流程控制和集合。 表达式&#xff1a;变量、常量、字面量和运算符 流程控制&#xff1a;分支、循环、函数和异常 集合&#xff1a;字符串、数组…

华为FreeBuds Pro 4丢了如何找回?(附查找功能使用方法)

华为FreeBuds Pro 4查找到底怎么用&#xff1f;华为FreeBuds Pro 4有星闪精确查找和离线查找&#xff0c;离线查找功能涵盖播放铃声、导航定位、星闪精确查找、上线通知、丢失模式、遗落提醒等。星闪精确查找是离线查找的子功能&#xff0c;当前仅华为FreeBuds Pro 4充电盒支持…