C++ 字符串OJ

目录

1、14. 最长公共前缀

2、 5. 最长回文子串

3、 67. 二进制求和

4、43. 字符串相乘


1、14. 最长公共前缀

 思路一:两两字符串进行比较,每次比较过程相同,可以添加一个函数辅助比较,查找最长公共前缀。

class Solution {
public:string longestCommonPrefix(vector<string>& strs) {string ret = strs[0];for (int i = 0; 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);}
};

思路二:选取一个字符串与其他字符串逐位比较,比较过程中如果有一个字符串能遍历到最后或某个字符与当前比较的字符不相等,则该字符串为最长公共前缀。

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

2、 5. 最长回文子串

 

 思路:中心扩展法

  • 中心扩展法:这种方法的核心思想是,回文子串的构造是对称的,所以可以从中心开始向两边扩展,检查两边的字符是否相等。这种方法需要考虑奇数长度和偶数长度的回文子串,因此对每个字符尝试两次扩展:一次将其视为中心(奇数长度),一次将其和下一个字符共同视为中心(偶数长度)。

  • 时间复杂度:由于需要对字符串中的每个字符都尝试向两边扩展,最坏情况下每次扩展可能会遍历整个字符串,因此总的时间复杂度为O(n^2),其中n是字符串的长度。

  • 空间复杂度:这个算法只使用了固定的额外空间(beginlen等变量),因此空间复杂度为O(1)。

通过这种方法,即使在字符串长度较长的情况下,也能有效地找到最长的回文子串。

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);}
};
  1. 首先,定义了三个变量:begin(记录最长回文子串的起始位置)、len(记录最长回文子串的长度)、n(记录字符串s的长度)。

  2. 然后,通过一个循环遍历字符串s中的每个字符。在循环中,以当前字符为中心,向两边扩展,找到以当前字符为中心的最长回文子串长度。

  3. 在第一个循环中,以当前字符为中心,向左右两边扩展,直到不再满足回文条件(即字符不相等或越界)。在扩展的过程中,记录下当前回文子串的起始位置和长度。

  4. 接着,在第二个循环中,以当前字符和下一个字符为中心,向左右两边扩展,找到以这两个字符为中心的最长回文子串长度。

  5. 在每次扩展过程中,比较当前找到的回文子串长度与之前记录的最长回文子串长度,如果当前找到的更长,则更新beginlen

  6. 最后,返回找到的最长回文子串,通过使用substr函数从原始字符串s中截取出最长回文子串。

3、 67. 二进制求和

 思路:模拟列竖式计算,注意二进制求和逢二进一。

class Solution {
public:string addBinary(string a, string b) {int cur1 = a.size() - 1, cur2 = b.size() - 1;string ret;int t = 0;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;}
};

4、43. 字符串相乘

 思路一:无进位相加,这个算法的关键在于通过逐位相乘和处理进位来实现大数乘法,避免了直接使用大数运算,使得算法能够处理非常大的数。

class Solution {
public:string multiply(string num1, string num2) {reverse(num1.begin(), num1.end());reverse(num2.begin(), num2.end());int m = num1.size(), n = num2.size();vector<int> tmp(m + n - 1);for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {tmp[i + j] += (num1[i] - '0') * (num2[j] - '0');}}int cur = 0, t = 0;string ret;while (cur < m + n - 1 || t) {if (cur < m + n - 1) {t += tmp[cur++];}ret += t % 10 + '0';t /= 10;}while (ret.size() > 1 && ret.back() == '0') {ret.pop_back();}reverse(ret.begin(), ret.end());return ret;}
};

 整个过程模拟了人工进行乘法计算的过程,先计算每一位的乘积然后逐步处理进位,最后得到结果。这种方法不依赖于任何大数处理库,能够处理非常大的数的乘法,只受限于内存和处理时间。

  1. 反转字符串:首先,将num1num2两个字符串反转,这样做是为了从最低位开始计算乘积,便于后续的逐位相乘和累加。

  2. 初始化临时数组:创建一个长度为m + n - 1的临时数组tmp,用于存储乘积的每一位。这里mn分别是num1num2的长度。数组的长度之所以是m + n - 1,是因为两个数最多可以产生这么长的乘积。

  3. 逐位相乘:遍历num1num2的每一位,将每一位的乘积累加到tmp数组对应的位置上。这里使用(num1[i] - '0') * (num2[j] - '0')来计算两位数字的乘积,并累加到tmp[i + j]上。

  4. 处理进位:遍历tmp数组,将每一位的值加上前一位的进位t,然后计算当前位的值(t % 10)和新的进位(t / 10)。这一步确保了每一位上的数字都是单个数字,并且正确处理了进位。

  5. 去除前导零:由于最开始反转了字符串,最终得到的结果也是反转的,且可能包含前导零。因此,需要去除结果字符串尾部的所有'0',直到结果字符串的长度大于1或者最后一个字符不是'0'。

  6. 反转结果字符串:最后,将结果字符串再次反转,得到正确的乘积结果。

  7. 返回结果:返回处理后的结果字符串。

思路二: 直接模拟

class Solution {
public:string multiply(string num1, string num2) {if (num1 == "0" || num2 == "0")return "0";int n1 = num1.size(), n2 = num2.size();string result(n1 + n2, '0');for (int i = n1 - 1; i >= 0; i--) {for (int j = n2 - 1; j >= 0; j--) {int product = (num1[i] - '0') * (num2[j] - '0') +(result[i + j + 1] - '0');result[i + j + 1] = product % 10 + '0';result[i + j] += product / 10;}}size_t startpos = result.find_first_not_of("0");return result.substr(startpos);}
};
  1. 特殊情况处理:如果num1num2中任何一个是"0",则乘积也是"0",直接返回"0"。

  2. 初始化结果字符串:创建一个长度为n1 + n2的字符串result,所有位初始化为'0'。这是因为两个长度分别为n1n2的数相乘,其结果长度最多为n1 + n2

  3. 逐位相乘并累加:从num1num2的最低位开始(即字符串的末尾),对每一对位进行乘法运算,并将乘积累加到结果字符串的相应位置。这里需要注意的是,乘积需要加上结果字符串中已经存在的数值(因为可能之前已经有累加的结果),所以使用(result[i + j + 1] - '0')来获取并更新结果。

  4. 处理进位:计算每一步的乘积后,可能会产生进位。进位被加到下一位的累加结果中。这里通过result[i + j + 1] = product % 10 + '0';来更新当前位的结果,并通过result[i + j] += product / 10;来处理进位。

  5. 去除前导零:由于初始化结果字符串时所有位都是'0',乘积的计算可能会在结果字符串的前面留下一些不必要的零。使用find_first_not_of("0")找到第一个非零字符的位置,并使用substr方法截取从这个位置到字符串末尾的子串作为最终结果。

  6. 返回结果:如果结果字符串中没有找到非零字符(即find_first_not_of返回string::npos),则说明结果为0;否则,返回去除前导零后的结果字符串。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/734801.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】函数模板和类模板

目录 1.泛型编程 2.函数模板 2.1函数模板的定义格式 2.2函数模板的实例化 2.3函数模板参数的匹配原则 3.类模板 3.1类模板的定义格式 3.2类模板的实例化 3.3模板的分离编译 1.泛型编程 泛型编程&#xff1a;编写与类型无关的通用代码&#xff0c;是代码复用的一种手段…

【前端CSS】CSS的3种基本选择器和5种高级选择器使用方式

目录 前言 基本选择器 1.1 标签选择器 1.2 ID选择器 1.3 类选择器 高级选择器 2.1 并集选择器 2.2 交集选择器 2.3 后代选择器 2.4 子元素选择器 2.5 属性选择器 前言 1W&#xff1a;什么是CSS选择器&#xff1f; CSS选择器由HTML元素的id、class属性或元素名本身以及…

SpringBoot中定时任务、corn表达式

SpringBoot中定时任务、corn表达式 corn表达式网站&#xff1a;https://cron.qqe2.com/ 方法上加上Scheduled(cron表达式) 启动类上加上EnableScheduling 示例 启动类上 启动类加上EnableScheduling开启定时任务。 SpringBootApplication EnableScheduling public class…

vue 在什么情况下在数据发生改变的时候不会触发视图更新

在 Vue 中&#xff0c;通常数据发生变化时&#xff0c;视图会自动更新。但是&#xff0c;有几种情况可能导致数据变化不会触发视图更新&#xff1a; 1.对象属性的添加或删除&#xff1a; Vue 无法检测到对象属性的添加或删除。因为 Vue 在初始化实例时对属性执行了 getter/se…

VUE3 使用axios网络请求

1.新建工程 参考&#xff0c;VUE3 环境搭建&#xff1a;https://blog.csdn.net/LQ_001/article/details/136293795&#xff0c;运行命令 vue create vue-demo 2.引入axios 不管何种引用&#xff0c;都要在工程中安装 axios 包。安装命令&#xff1a;npm install --save axio…

C语言——函数指针——函数指针变量(详解)

函数指针变量 函数指针变量的作用 函数指针变量是指向函数的指针&#xff0c;它可以用来存储函数的地址&#xff0c;并且可以通过该指针调用相应的函数。函数指针变量的作用主要有以下几个方面&#xff1a; 回调函数&#xff1a;函数指针变量可以作为参数传递给其他函数&…

拿捏算法的复杂度

目录 前言 一&#xff1a;算法的时间复杂度 1.定义 2.简单的算法可以数循环的次数&#xff0c;其余需要经过计算得出表达式 3.记法&#xff1a;大O的渐近表示法 表示规则&#xff1a;对得出的时间复杂度的函数表达式&#xff0c;只关注最高阶&#xff0c;其余项和最高阶…

【音视频开发好书推荐2】《FFmpeg 音视频开发基础与实战》

1、多媒体处理开源库FFmpeg概述 享有盛名的音视频多媒体处理开源库FFmpeg&#xff0c;做过音视频编解码开发的同学基本都用过&#xff0c;即便没做过这方面开发&#xff0c;也会听说过这个开源库。 FFmpeg是目前最全面的开源音视频编解码库&#xff0c;包括常用的音视频编码协议…

JavaScript原型和原型链

JavaScript每个对象拥有一个原型对象 需要注意的是&#xff0c;只有函数对象才有 prototype 属性 当试图访问一个对象的属性时&#xff0c;它不仅仅在该对象上搜寻&#xff0c;还会搜寻该对象的原型&#xff0c;以及该对象的原型的原型&#xff0c;依次层层向上搜索&#xff…

C++指针(五)完结篇

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 前言 相关文章&#xff1a;C指针&#xff08;一&#xff09;、C指针&#xff08;二&#xff09;、C指针&#xff08;三&#xff09;、C指针&#xff08;四&#xff09;万字图文详解&#xff01; 本篇博客是介…

ai学习前瞻-python环境搭建

python环境搭建 Python环境搭建1. python的安装环境2. MiniConda安装3. pycharm安装4. Jupyter 工具安装5. conda搭建虚拟环境6. 安装python模块pip安装conda安装 7. 关联虚拟环境运行项目 Python环境搭建 1. python的安装环境 ​ python环境安装有4中方式。 从上图可以了解…

物联网电气融合实训室建设方案

1 教学实训总体设计 1.1 建设背景 &#xff08;一&#xff09;政策推动与战略部署 近年来&#xff0c;物联网技术在全球范围内得到了广泛的关注和应用。作为信息技术的重要组成部分&#xff0c;物联网在推动经济转型升级、提升社会管理水平、改善民生福祉等方面发挥着重要作…

python实现桶排序

排序算法&#xff1a; python实现基数排序 python实现归并排序 python实现交换排序 python实现选择排序 python实现插入排序 python实现桶排序 桶排序&#xff08;Bucket Sort&#xff09;是一种排序算法&#xff0c;它将待排序的元素分到有限数量的桶&#xff08;buckets&…

Ps:清理

清理 Purge命令位于“编辑”菜单下&#xff0c;它主要用于释放 Photoshop 使用的内存资源&#xff0c;有助于提高系统的性能。 通过使用“清理”命令&#xff0c;用户可以有效管理 Photoshop 的资源使用&#xff0c;特别是在处理大型文件或进行长时间编辑会话时。 定期清理可以…

python 基础知识点(蓝桥杯python科目个人复习计划61)

今日复习内容&#xff1a;想到什么复习什么 因为比赛用到的编辑器是IDLE&#xff0c;所以从现在开始&#xff0c;我就不用pycharm了。 例题1&#xff1a; 从1到2020的所有数字中&#xff0c;有多少个2&#xff1f; 这个题是一个填空题&#xff0c;我用的方法是先在编辑器上…

第14章 西瓜书——概率图模型

概率图模型 概率图模型&#xff08;Probabilistic Graphical Model&#xff09;是用图结构来表示多元随机变量之间条件依赖关系的模型。在图模型中&#xff0c;节点表示随机变量&#xff0c;边表示变量之间的依赖关系。概率图模型可以分为有向图模型&#xff08;如贝叶斯网络&a…

Oracle VM VirtualBox安装Ubuntu桌面版

背景&#xff1a;学习Docker操作 虚拟机软件&#xff1a;Oracle VM VirtualBox 7.0 系统镜像&#xff1a;ubuntu-20.04.6-desktop-amd64.iso 在Oracle VM VirtualBox新建一个虚拟电脑 选择好安装的目录和选择系统环境镜像 设置好自定义的用户名、密码、主机名 选择一下运行内…

交易平台开发:构建安全/高效/用户友好的在线交易生态圈

在数字化浪潮的推动下&#xff0c;农产品现货大宗商品撮合交易平台已成为连接全球买家与卖家的核心枢纽。随着电子商务的飞速发展&#xff0c;一个安全、高效、用户友好的交易平台对于促进交易、提升用户体验和增加用户黏性至关重要。本文将深入探讨交易平台开发的关键要素&…

Mac使用自动操作(Automator)发送文件到Android设备

需求场景 在Android开发调试的过程中&#xff0c;当需要把电脑上的文件传输到连接的Android设备时&#xff0c;通常的做法是通过adb push命令。那既然是通过命令操作&#xff0c;是否可以通过可视化的工具来操作呢&#xff1f;例如在Finder中&#xff0c;右击某一个文件或者目…

软件测试相关内容第三弹--软件测试基础

写在前&#xff1a;在前篇的两篇博客介绍中我们主要学习软件测试的相关概念&#xff0c;对软件测试进行了初步的了解&#xff0c;本篇博客将进一步进行学习。重点内容包括&#xff1a;软件测试的生命周期、如何描述一个bug、如何定义bug的级别、bug的生命周期以及在实际工作中如…