目录

57 力扣14最长公共前缀

57.1 题目解析:

57.2 算法思路

57.3 代码演示:

​编辑 

57.4 总结反思:

58 力扣 5最长回文字符串

58.1 题目解析:

​编辑 

58.2 算法思路:

58.3 代码演示:

​编辑

58.4 总结反思:

59 力扣 模拟二进制之和

59.1 题目解析:

59.2 算法思路:

59.3 代码演示:

​编辑

59.4 总结反思

60. 力扣43 字符串相乘

60.1 题目解析:

60.2 算法思路:

60.3 代码演示:

60.4 总结反思

 


57 力扣14最长公共前缀

57.1 题目解析:

这道题目的题意很好理解吧。就是找这些字符串的最长的公共前缀即可

57.2 算法思路

 那么这道题目有几种解法。

解法一:解法一就是两两比较去找出公共前缀


 

那么这种解法就是两两的进行比较即可。那么此时的时间复杂度是O(m*n),m是字符串的个数,n是每一个字符串的长度(假设是相等的每一个字符串的长度)。

那么咱们再来看一个解法,就是解法二:

统一比较:

 

那么此时会出现两种情况得让i停止,咱们都得考虑到。

咱们这个的处理方法是先让i小于第一个字符串的长度,然后再定义一个j去竖着遍历,类似于二维数组,则i<str.size(),j小于strs的长度(即字符串的个数),然后strs[j][i]。就是第j行i列

57.3 代码演示:

咱们先来看一下解法一就是两两比较的:

 

string findCommon(string s1, string s2);
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);
}
int main()
{vector<string> strs = { "flower","flow","flight" };cout << longestCommonPrefix(strs) << endl;return 0;
}

解法二:

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 (tmp != strs[j][i] || i == strs[j].size())//当越界了,或者是字符串不相等的时候{return strs[0].substr(0, i);}}}return strs[0];
}
int main()
{vector<string> strs = { "flower","flow","flight" };cout << longestCommonPrefix(strs) << endl;return 0;
}

57.4 总结反思:

其实字符串类型的题目不只是字符串,还有其他相关的知识。比如模拟,等等

58 力扣 5最长回文字符串

58.1 题目解析:

 

题目很清晰,就是让你找到最长的回文子串

58.2 算法思路:

咱们可以使用中心扩展算法来做这道题目

 

最后返回的是这个字符串的left与right之间的元素个数。所以,可用substr(......)

58.3 代码演示:

string longestPalindrome(string s) {//中心扩展算法int begin = 0; int len = 0; int 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++;}while (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++;}while (right - left - 1 > len)//求最长{begin = left + 1;len = right - left - 1;}}return s.substr(begin, len);
}
int main()
{string s("babad");cout << longestPalindrome(s) << endl;return 0;
}

58.4 总结反思:

这道题目其实使用其他的方法也是可以去做的

59 力扣 模拟二进制之和

59.1 题目解析:

就是让你模拟如何进行二进制的相加,别忘了进位即可

59.2 算法思路:

大家看这个题,是不是跟那个两数之和(之前咱们使用链表做的那个题很像?)没错,就是一样的思路:

 

59.3 代码演示:

string addBinary(string a, string b) {int len1 = a.size();int len2 = b.size();string c;string d;string e;for (int i = len1 - 1; i >= 0; i--){c += a[i];}for (int j = len2 - 1; j >= 0; j--){d += b[j];}int t = 0;int cur1 = 0, cur2 = 0;while (cur1 < c.size() || cur2 < d.size() || t){if (cur1 < c.size()){t += c[cur1++] - '0';//字符转数字,字符串里面的全都是字符}if (cur2 < d.size()){t += d[cur2++] - '0';}e += t % 2 + '0';//数字转字符t /= 2;}reverse(e.begin(), e.end());return e;
}
int main()
{string a("1010");string b("1011");cout << addBinary(a, b) << endl;return 0;
}

这道题目咱们还是需要逆序一下子的,不过博主一开始的逆序方式挺智障的hhh,明明可以用reverse来逆序

59.4 总结反思

这道题目其实还可以,下面这一道题目才是王炸

60. 力扣43 字符串相乘

60.1 题目解析:

这道题目很好理解,但是不是很好做。我依稀记得,这道题目是我一开始学C++语法,刚学了一点,就开始做这道题目,当时,这道题目我做了6个小时,没错,你没看错,6个小时,不断地调试调试,可算是把那几个边界条件给调试了出来。但是我今天再去学习的时候,就发现了另外一种的优化方案。

60.2 算法思路:

 那么方法一就是普通的算式:

1. addStrings 函数:实现两个字符串表示的非负整数的相加。
思路:从两个字符串的末尾(个位)开始逐位相加,模拟竖式加法,注意进位。
具体步骤:
- 初始化:i 和 j 分别指向 num1 和 num2 的最后一个字符,index(表示进位)初始为0。
- 循环条件:当 i >= 0 或 j >= 0 时,说明还有数字没有加完。
- 在循环内:
ret = 0;
如果 i >= 0,则将 num1[i] 转换为数字并加到 ret 上,然后 i--。
如果 j >= 0,则将 num2[j] 转换为数字并加到 ret 上,然后 j--。
如果进位 index > 0(注意这里index是上一位的进位,初始为0,但每次进位后会被重置,所以每次循环最多只会有一次进位加入),将进位加到 ret 上,并把 index 置0。
判断 ret 是否 >= 10,如果是,则计算新的进位 index = ret / 10(实际上就是1,因为两个一位数相加最大18,所以进位只能是1,但这里用除法更通用),然后 ret %= 10。
将 ret 转换为字符,添加到结果字符串 ans 中。
- 循环结束后,如果还有进位(index > 0),则在结果后面添加一个'1'(因为进位最多为1)。
- 由于我们是从个位开始加,结果字符串是逆序的,所以最后需要反转整个字符串。
2. multiply 函数:使用加法模拟乘法。
思路:模拟竖式乘法,将乘数的每一位与被乘数相乘,然后累加,注意乘数每一位的权重(后面要补零)。
具体步骤:
- 如果其中一个数为"0",则直接返回"0"。
- 初始化 ans 为空字符串。
- 从 num1 的个位开始(即从后往前)遍历每一位:
用当前位数字(记为ret)乘以 num2,这里通过连续调用 addStrings 函数来实现:用 while 循环,将 num2 累加 ret 次(注意:ret是数字,比如'5',则累加5次)。得到的结果就是当前位与num2的乘积(字符串形式)。
然后把这个乘积加到最终结果 ans 上(用addStrings)。
将 num2 后面添加一个'0'(相当于乘以10),因为下一位是十位,所以被乘数需要扩大10倍(在竖式中,我们通常向左移位)。

解法二就是优化,即无进位相乘然后相加,最后再处理进位

 

模拟竖式乘法的另一种方式,先忽略进位,将每一位相乘的结果累加到一个临时数组中,然后统一处理进位。
具体步骤:
- 首先反转两个字符串,使得从低位到高位排列(即下标0对应个位)。
- 创建一个临时数组 tmp,大小为 m + n - 1(两个数相乘,结果位数最多为m + n,最少为m + n - 1,这里先按最少分配,后面进位可能会增加位数)。
- 第一步:无进位相乘后相加。
遍历 num1 的每一位(反转后)和 num2 的每一位,将相乘的结果加到 tmp 数组的对应位置(tmp[i + j])上。
注意:这里 i 和 j 分别从0开始,所以 i + j 就是两个数位相乘结果应该放的位数(个位乘个位放在0号位置,十位乘个位放在1号位置,以此类推)。
- 第二步:处理进位。
初始化 cur = 0(当前处理的位置),t = 0(进位),以及结果字符串 ret。
循环条件:cur 小于 m + n - 1(即还有位数未处理)或者 t 不为0(还有进位未处理完)。
在循环内:
如果 cur 还在数组范围内,则取出当前位的值加到 t 上,然后 cur++。
将 t 的个位(t % 10)转换为字符加到 ret 的末尾。
将 t 除以10(得到进位),继续下一位。
- 第三步:处理前导零。
        由于我们是从低位到高位处理,所以结果字符串是逆序的(个位在最前面,最高位在最后面),而且可能有前导零(比如最后几位进位后可能变成0,但我们处理进位时已经将进位处理完,所以最后几位可能是0,但实际结果中不应该有前导零)。
        注意:在反转之前,我们的字符串是低位在前,所以最后连续的0在字符串的尾部(在反转后会变成前导零)。但是我们在处理进位时,最后可能多出进位,所以字符串长度可能大于实际位数。不过,在第二步中,我们处理进位时已经将所有的位数都处理了,包括进位,所以最后得到的字符串应该是正确的,但是可能有前导零(在反转后变成前导零,但此时我们还没有反转)。
        然而,在第二步中,我们是从低位到高位处理,得到的结果字符串也是低位在前。在反转之前,我们需要去掉字符串末尾的0(因为反转后这些0会变成前导零)。但是注意:如果结果就是0,那么我们应该保留一个0。
        所以,循环:当 ret 的长度大于1且最后一个字符是'0'时,删除最后一个字符(即反转前,我们删除字符串尾部的0,这些0在反转后会变成前导零)。
- 反转字符串,得到最终结果。 

好,那么咱们可以推导出方法一的效率低(大数字时性能差) 。但是方法二的效率高(适合大数运算)。

60.3 代码演示:

方法一:

//方法一:
string addStrings(string num1, string num2) {string ans; // 存储结果int index = 0;// 进位,初始为0int i = num1.size() - 1;// 从num1的个位开始int j = num2.size() - 1;// 从num2的个位开始while (i >= 0 || j >= 0) {int ret = 0;if (i >= 0)ret += num1[i] - '0';// 取num1当前位数字if (j >= 0)ret += num2[j] - '0';// 取num2当前位数字if (index > 0) { // 如果有进位,则加上进位ret += index;index = 0; // 进位已经加入,清零}if (ret >= 10) {// 如果相加结果大于等于10,需要进位index = ret / 10;// 计算进位(这里ret最多19,所以进位为1,但写法通用)ret %= 10; // 取余数}ans.push_back('0' + ret);// 将当前位的数字转为字符,加入结果j--;// 移动指针i--;}if (index > 0) // 如果最后还有进位ans.push_back('1');// 在结果末尾加上进位1(因为进位最多为1)reverse(ans.begin(), ans.end()); // 反转字符串return ans;
}
string multiply(string num1, string num2) {if (num1 == "0" || num2 == "0")// 处理乘数为0的情况return "0";string ans;for (int i = num1.size() - 1; i >= 0; i--) {// 从num1的个位开始string str;// 用来存储当前位乘以num2的结果int ret = num1[i] - '0'; // 当前位的数字while (ret--) { // 循环ret次,相当于乘以retstr = addStrings(str, num2);// 累加num2}// 将当前结果加到总和中ans = addStrings(ans, str);// 为下一位做准备:num2后面加0,相当于乘以10(因为下一位是十位,在竖式中要左移一位)num2 += '0';}return ans;
}
int main()
{string num1("123");string num2("456");cout << addStrings(num1,num2) << endl;return 0;
}
  1. 字符串加法

    • 从个位开始逐位相加,处理进位。

    • 结果需要反转(计算时低位在前)。

  2. 乘法实现

    • 遍历num1的每一位,将其与num2相乘(通过累加实现)。

    • 每次处理更高位时,在num2末尾补0(等价于左移一位,权重×10)。

方法二:

//方法二:在方法一上面进行了改良,优化
string multiply(string n1, string n2)
{// 解法:⽆进位相乘后相加,然后处理进位int m = n1.size(), n = n2.size();// 反转字符串,使得低位(个位)在索引0位置reverse(n1.begin(), n1.end());reverse(n2.begin(), n2.end());// 创建临时数组,大小为m+n-1(因为两个数相乘,结果位数最小为m+n-1,比如100*100=10000有5位,最大为m+n)// 但这里我们使用m+n-1,后面进位可能会增加位数vector<int> tmp(m + n - 1);// 1. ⽆进位相乘后相加for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)tmp[i + j] += (n1[i] - '0') * (n2[j] - '0');// 2.  处理进位int cur = 0, t = 0;// cur: 当前处理到tmp的哪个位置,t:进位string ret;// 循环条件:cur还没到tmp数组末尾,或者还有进位twhile (cur < m + n - 1 || t){if (cur < m + n - 1) t += tmp[cur++]; // 取出当前位的值加入进位t,并移动curret += t % 10 + '0';// 取个位加入结果字符串t /= 10;// 更新进位}// 3. 处理前导零while (ret.size() > 1 && ret.back() == '0') ret.pop_back();reverse(ret.begin(), ret.end());return ret;
}
int main()
{string num1("123");string num2("456");cout << addStrings(num1, num2) << endl;return 0;
}
  1. 无进位相乘

    • 反转字符串使低位在前(下标0对应个位)。

    • 双重循环计算n1[i] * n2[j],结果累加到tmp[i + j]

  2. 统一处理进位

    • 从低位到高位遍历tmp,将累加值加上进位后,按位存储并更新进位。

  3. 前导零处理

    • 删除结果字符串末尾多余的0(反转前末尾对应高位)。

    • 反转字符串使高位在前。

 

60.4 总结反思

这道题目可谓是真的锻炼你的代码能力以及边界处理能力

本篇完.................. 

 

 

 

 

 

 

 

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

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

相关文章

四、Portainer图形化管理实战与Docker镜像原理

作者&#xff1a;IvanCodes 日期&#xff1a;2025年8月2日 专栏&#xff1a;Docker教程 一、Portainer 安装与基础使用教程 Portainer 是一个轻量级、功能强大的Docker图形化管理界面 (GUI)。它能让你通过简单的Web界面来管理和监控你的Docker容器、镜像、卷、网络等资源&…

网络爬虫(python)入门

一、网络爬虫介绍 网络爬虫&#xff08;Web Crawler&#xff09;是一种自动抓取互联网信息的程序&#xff0c;它能够高效地从海量网页中提取有价值的数据。作为数据采集的利器&#xff0c;爬虫技术在数据分析、搜索引擎、价格监控等领域有着广泛应用。本文将带你全面了解Pytho…

如何解决pip安装报错ModuleNotFoundError: No module named ‘plotnine’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘plotnine’问题 一、摘要 在使用 PyCharm 进行 Python 开发时&#xff0c;常常需要通过 pip install 安装第三方包。某天&#xff0c;你在终端或 PyCharm 控制…

语校网收录东京语言学校150所:数据结构建模与工程实现全解

语校网收录东京语言学校150所&#xff1a;数据结构建模与工程实现全解 一、为什么语言学校的信息抓取如此困难&#xff1f; 在日语教育领域&#xff0c;“语言学校”是一类极度碎片化的机构体系&#xff0c;尤其在东京地区&#xff0c;2025年时点上已合法设立的语言学校已超1…

【按下电源键后,电脑里发生了什么?——BIOS:启动世界的“第一把钥匙”】

当你按下电源键的瞬间&#xff0c;电脑从一片死寂中“苏醒”。但你是否想过&#xff1a;是什么让屏幕亮起、风扇转动、硬件逐一激活&#xff1f; 这背后&#xff0c;有一个隐藏在主板上的“小程序”在默默掌控全局——它就是 BIOS&#xff08;Basic Input/Output System&#x…

局域网五子棋工具 多人对战无限制

软件介绍 今天推荐一款经典的PC端五子棋游戏——GoBang&#xff0c;绿色免安装版本&#xff0c;完全免费&#xff0c;即开即用&#xff0c;轻松享受对弈乐趣。 游戏模式 软件提供三种对战模式&#xff1a;人人对战、人机对抗以及局域网联机游戏&#xff0c;满足不同玩家的社…

分布式弹幕系统设计

需求:分布式弹幕广播分布式方案1:适用redis 发布订阅来进行不同ws服务器之间的通信优点:适用小系统方案2:对ws服务器进行一致性hash获取ws服务的接入点优点:大型系统缺点:视频连接不均匀挑战点:广播速度聚合广播和线程池来进行优化

梦幻花瓣雨

1. 花瓣设计四种花瓣类型&#xff1a;创建了四种不同形状和颜色的花瓣&#xff08;粉红、淡紫、浅粉和蓝绿色&#xff09;自然形态&#xff1a;使用CSS渐变和复杂边框半径模拟真实花瓣的不规则形状柔和阴影&#xff1a;为花瓣添加微妙的阴影增强立体感2. 动画效果物理模拟&…

React 闭包陷阱及解决方案与 React 16/17/18 版本区别

一、React 闭包陷阱详解1. 什么是闭包陷阱React 闭包陷阱是指在函数组件中使用 Hook&#xff08;特别是 useEffect 和 useCallback&#xff09;时&#xff0c;由于闭包特性导致访问到旧的 state 或 props 值&#xff0c;而非最新值的现象。2. 典型场景示例function Counter() {…

[BJDCTF2020]EasySearch

首先尝试了一下sql注入&#xff0c;但是没有找到不同回显。直接用sqlmap扫描一下&#xff0c;因为这边用的是POST请求&#xff0c;所以需要抓包将请求复制到txt文件中然后使用命令sqlmap -p bp.txt。也没有发现注入漏洞。 再进行目录扫描试试&#xff1a; [02:33:43] 403 - …

【Linux】基本指令的使用 and 面试常问

1、man 指令使用方法&#xff1a;man Linux指令。功能&#xff1a;相当于字典&#xff0c;查找指令的用法。常用选项&#xff1a;-k&#xff1a;根据关键字搜索联机帮助。num&#xff1a;只在第num章节查找。-a&#xff1a;将所有章节的都显示出来&#xff0c;比如man printf它…

零基础 “入坑” Java--- 十六、字符串String 异常

文章目录一、String1.字符串的不可变性2.字符串的修改3.StringBuilder和StringBuffer4.【字符串练习】4.1 字符串中的第一个唯一字符4.2 字符串最后一个单词的长度4.3 验证回文串二、异常1.初识异常2.异常的分类3.异常的处理4.异常处理流程总结5.自定义异常在上一章节中&#x…

梯度下降在大模型训练中的作用与实现

梯度下降&#xff08;Gradient Descent&#xff09;是深度学习中最核心的优化算法之一。大模型&#xff08;如GPT、BERT&#xff09;在训练时需要优化数十亿甚至上千亿的参数&#xff0c;而梯度下降及其变体&#xff08;如SGD、Adam&#xff09;正是实现这一优化的关键工具。它…

【JVS更新日志】开源框架、APS排产、企业计划、物联网、逻辑引擎7.30更新说明!

项目介绍 JVS是企业级数字化服务构建的基础脚手架&#xff0c;主要解决企业信息化项目交付难、实施效率低、开发成本高的问题&#xff0c;采用微服务配置化的方式&#xff0c;提供了低代码数据分析物联网的核心能力产品&#xff0c;并构建了协同办公、企业常用的管理工具等&…

Eclipse中导入新项目,右键项目没有Run on Server,Tomcat的add and remove找不到项目

原因分析没有勾选Dynamic Web Module、Java、JavaScriptDynamic Web Module版本问题解决方法Eclipse中右键项目选择Properties左侧点击project facets勾选Dynamic Web Module、Java、JavaScript&#xff0c;注意Dynamic Web Module版本问题,要和tomcat版本对应。- Dynamic Web …

IntelliJ IDEA 2025系列通用软件安装教程(Windows版)

前言 JetBrains系列开发工具&#xff08;如IntelliJ IDEA、PyCharm、WebStorm等&#xff09;是程序员们非常喜爱的集成开发环境。2025年最新版本带来了更多强大的功能和改进。本教程将详细介绍如何在Windows系统上安装JetBrains 2025系列软件。 最近挖到一个宝藏级人工智能学习…

乌鸫科技前端二面

1. 你能给我介绍一下你参与的重要项目&#xff0c;并重点介绍一下做的内容?通俗解释&#xff1a; 挑一个你觉得最拿得出手、技术含量最高的项目&#xff0c;说说这个项目是干什么的&#xff08;比如一个电商网站、一个后台管理系统&#xff09;&#xff0c;你在里面具体负责了…

《c++面向对象入门与实战》笔记

前年的书&#xff0c;翻出来整理一下7章.指针指针 sizeof为4*指针 sizeof为 所指类型的sizeof注意free后置空&#xff0c;避免野指针11章.类

easyExcel生成多个sheet的动态表头的实现

在使用 EasyExcel 实现“多个 Sheet 且每个 Sheet 表头是动态的”需求时&#xff0c;思路如下&#xff1a;✅ 实现思路概述 EasyExcel 的 ExcelWriter 支持多个 Sheet 写入。每个 Sheet&#xff1a; 使用 WriteSheet 创建&#xff1b;可以绑定一个动态生成的表头 List<List&…

SQL 连接类型示例:内连接与外连接

SQL 连接类型示例&#xff1a;内连接与外连接 示例数据表 假设我们有两个表&#xff1a; employees 表:emp_idemp_namedept_id1张三1012李四1023王五1034赵六NULLdepartments 表:dept_iddept_name101销售部102技术部104财务部1. 内连接 (INNER JOIN) 内连接只返回两个表中匹配的…