【算法】字符串算法技巧系列
阿华代码,不是逆风,就是我疯
你们的点赞收藏是我前进最大的动力!!
希望本文内容能够帮助到你!!
目录
引入:字符串相关算法技巧
1:字符串转数组
2:子字符串
3:数组转字符串
4:字符串拼接方式
5:返回字符串指定下标的字符
6:StringBuilder/StringBuffer用法
7:Integer类型转换为String类型
一:最后一个单词的长度
二:最长公共前缀
三:最长回文子串(ex)
四:二进制求和
五:找字符串中第一个匹配项的下标
六:字符串相乘
引入:字符串相关算法技巧
1:字符串转数组
String a = “abcdefg” char[] a1= a.toCharArray()
//将字符串数组转换为字符数组(常用)
.charAt(下标0~length()-1)
//返回下标对应的字符。字符串长度是length() 数组没有括号
2:子字符串
.substring():
截取字符串中介于两个指定下标之间的字符,第一个字符下标为0
注意:(就是小写)两个参数:截取的结果,不包括结束位置的字符。一个参数:从起始位置至字符串末尾的字符串
3:数组转字符串
String.ValueOf(数组名称);
4:字符串拼接方式
方式一:
String ret = " ";
ret += num[i];
方式二:
5:返回字符串指定下标的字符
字符串的名字.charAt(下标);
6:StringBuilder/StringBuffer用法
(1) StringBuilder性能更好,StringBuffer线程更安全,两者方法一样
(2)append追加字符,字符拼接,
(3)计算长度 .length()
(4)删除指定位置的元素 .deleteCharAt()
(5)转化为字符串 .toString()
(6)反转字符 .reverse();返回类型是StringBuffer或StringBuilder
StringBuilder下的toString方法,把拼接的内容以字符串的形式输出。
7:Integer类型转换为String类型
Integer.toString(num1 - num2);
一:最后一个单词的长度
58. 最后一个单词的长度
这个边界问题,老生常谈了,非常重要啊!!老弟

class Solution {public int lengthOfLastWord(String s) {int n = s.length();StringBuffer buffer = new StringBuffer();for (int i = n - 1; i >= 0;) {while(i >= 0 && s.charAt(i) == ' '){i--;}while (i >= 0 && s.charAt(i) != ' ') {buffer.append(s.charAt(i));i--;}break;}return buffer.length();}
}
二:最长公共前缀
14. 最长公共前缀
要退出两层for循环的话,可以很巧妙的引入一个标志符作为参考。同样也可以在for循环中返回结果,女少~!!

class Solution {public String longestCommonPrefix(String[] strs) {String str = strs[0];if (str == "") {return "";}int n = strs.length;// 数组的长度int m = strs[0].length();// 第一个字符串的长度StringBuffer buffer = new StringBuffer();int target = 0;for (int i = 0; i < m; i++) {// i表示第一个字符串中字符的下标char ch = strs[0].charAt(i);for (int j = 1; j < n; j++) {// j表示数组中第几个字符串String curStr = strs[j];int curStrLen = curStr.length();if (i > curStrLen - 1 || curStr.charAt(i) != ch) {// 当前下标的比较// target = -1;// break;return buffer.toString();}}// if(target == -1){// break;// }buffer.append(ch);}return buffer.toString();//如果for循环中没有返回的话,说明所有元素都是相等的,直接返回即可}
}
三:最长回文子串(ex)
心得感悟:这道题我的奇偶性分情况思路是正确的,但是边界情况处理的跟一坨*一样,尤其是while循环条件的书写,思路清晰是最重要的,在就是子字符串 算法工具还需要熟悉,这道题到是不难,中心扩展算法还是很好理解的。
下面的板书画图是我一开始的思路,大体方向正确,但代码冗杂


class Solution {public String longestPalindrome(String s) {int n = s.length();if (n == 1) return s;int ret = 1; // 最大回文长度String str = s.substring(0, 1); // 初始化结果字符串int left = 0, right = 0;for (int cur = 0; cur < n; cur++) { // 从第一个字符开始// 检查以 cur 为中心的奇数长度回文left = cur; right = cur;while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {left--;right++;}int curLen = right - left - 1;if (curLen > ret) {ret = curLen;str = s.substring(left + 1, right); // 截取回文子串}// 检查以 cur 和 cur+1 为中心的偶数长度回文left = cur; right = cur + 1;while (left >= 0 && right < n && s.charAt(left) == s.charAt(right)) {left--;right++;}curLen = right - left - 1;if (curLen > ret) {ret = curLen;str = s.substring(left + 1, right); // 截取回文子串}}return str;}
}
四:二进制求和
思路正确但是麻烦并且数据大了会溢出,(超过long64位时)
class Solution {public String addBinary(String a, String b) {long num1 = 0 , num2 = 0;char[] aa = a.toCharArray();char[] bb = b.toCharArray();// 将2进制转化为10进制for(char ch : aa){num1 = 2 * num1 + switchNum(ch);}for(char ch : bb){num2 = 2 * num2 + switchNum(ch);}long ret = num1 + num2;if(ret == 0) return "0";StringBuffer buffer = new StringBuffer();while(ret != 0){buffer.append(ret % 2 == 1 ? '1' : '0');ret = ret / 2;} return buffer.reverse().toString();}public int switchNum(char ch){switch (ch){case '1':return 1;case '0':return 0; }return -1; }
}
思路二:能行得通,但罗里吧嗦
class Solution {public String addBinary(String a, String b) {int len1 = a.length() , len2 = b.length();int cur1 = len1-1 , cur2 = len2-1;int tmp = 0;StringBuilder builder = new StringBuilder();while(cur1 >= 0 || cur2 >= 0){if(cur1 >= 0){tmp += a.charAt(cur1) == '0' ? 0 : 1;cur1--;}if(cur2 >= 0){tmp += b.charAt(cur2) == '0' ? 0 : 1;cur2--;}if(tmp == 0){builder.append('0'); }else if(tmp == 1){builder.append('1');tmp = 0;}else if(tmp == 2){builder.append('0');tmp = 1;}else if(tmp == 3){ //穷举法(包含进位的数字)builder.append('1');tmp = 1;}}if(tmp == 1){builder.append('1');//处理最前端还有进位的情况}return builder.reverse().toString();}
}
五:找字符串中第一个匹配项的下标
28. 找出字符串中第一个匹配项的下标

class Solution {public int strStr(String haystack, String needle) {String str1 = haystack, str2 = needle;char ch = str2.charAt(0);char[] s1 = str1.toCharArray();int n = s1.length, m = str2.length() , ret = -1;if (n < m) return -1;boolean sign = false;for (int i = 0; i <= n - m;) {if (s1[i] != ch) i++;if (i == n - m) {//单独处理一下最后长度一样的字符串n-m是剩下的长度上限,下标上限就是n-m这种情况单独处理sign = str1.substring(i).equals(str2);} else if (i < n - m) {sign = str1.substring(i, i + m).equals(str2);}if (sign == true) {ret = i;break;} else {i++;}}return ret;}
}
六:字符串相乘
43. 字符串相乘
tip:被这道题恶心坏了,首先这道题关键在于,下标的确定,关键步骤一,确定好nums3数组,关键步骤二遍历nums3数组确定进位,模拟相加。
这道题暴露出来:
整型转字符—— (char)(nums3[j]%10 + '0') 重点重点!!!
字符转整型——str1.charAt(i)-'0'


class Solution {public String multiply(String num1, String num2) {if(num1.charAt(0) == '0' || num2.charAt(0) == '0') return "0";int n1 = num1.length() , n2 = num2.length();int n3 = n2 + n1 - 1;int[] nums3 = new int[n3];StringBuilder builder1 = new StringBuilder(num1);StringBuilder builder2 = new StringBuilder(num2);String str1 = builder1.reverse().toString();String str2 = builder2.reverse().toString();for(int i = 0 ; i < n1 ; i++){for(int j = 0 ; j < n2 ; j++){nums3[i+j] += (str1.charAt(i)-'0')*(str2.charAt(j)-'0');}}StringBuilder builder3 = new StringBuilder();int tmp = 0;for(int j = 0 ; j < n3 ; j++){tmp = nums3[j]/10;//进位的builder3.append((char)(nums3[j]%10 + '0'));if(j < n3-1){nums3[j+1] += tmp;}if(j == n3-1 && nums3[j] >= 10){builder3.append((char)(tmp + '0'));}}String ret = builder3.reverse().toString();return ret;}
}
七:验证回文串
125. 验证回文串
这道题暴露出来的问题,大小写转换还不太熟悉,对于字符数组leetcode不支持进行foreach循环遍历


class Solution {public boolean isPalindrome(String s) {if(s == "") return true;//先转化为纯的字符串int len = s.length();StringBuilder builder = new StringBuilder();for(int i = 0 ; i < len ; i++){char ch = s.charAt(i);if((ch >= 'a' && ch <='z') || (ch >= 'A' && ch <='Z') || (ch >= '0' && ch <='9') ){builder.append(ch);}}String str = builder.toString().toLowerCase();int n = str.length();int left = 0 , right = n-1;while(left >= 0 && right <= n-1){if(n % 2 == 0){left = (0 + n - 1)/2;right = left+1;while(left >= 0 && right <= n-1){if(str.charAt(left) == str.charAt(right)){left--;right++;}else{return false;}}}if(n % 2 == 1){left = (0 + n - 1)/2;; right = left;while(left >= 0 && right <= n-1){if(str.charAt(left) == str.charAt(right)){left--;right++;}else{return false;}}}}return true;}
}
八:判断子序列
392. 判断子序列

class Solution {public boolean isSubsequence(String s, String t) {int n1 = s.length() , n2 = t.length();if(n1 > n2) return false;int cur1 = 0 , cur2 = 0;while(cur1 < n1 && cur2 < n2){if(cur1 < n1 && cur2 < n2 && s.charAt(cur1) == t.charAt(cur2)){cur1++;cur2++;}else{cur2++;}}if(cur1 == n1 && cur2 <= n2){return true;}return false;}
}
相关文章:
【算法】字符串算法技巧系列
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 引入:字符串相关算法技巧 1:字符串转数组 2:子字符串 3ÿ…...
Vue中el-tree结合vuedraggable实现跨组件元素拖拽
实现效果: 左侧el-tree: <template><el-treeclass"filter-tree":data"treeData":props"defaultProps":filter-node-method"filterNode"node-key"id"draggable:allow-drop"allowDrop"node-dr…...
湘潭大学人机交互复习
老师没给题型也没划重点,随便看看复习了 什么是人机交互 人机交互(Human-Computer Interaction,HCI)是关于设计、评价和实现供人们使用的交互式计算机系统,并围绕相关的主要现象进行研究的学科。 人机交互研究内容 …...
基于ADAS 与关键点特征金字塔网络融合的3D LiDAR目标检测原理与算法实现
一、概述 3D LiDAR目标检测是一种在三维空间中识别和定位感兴趣目标的技术。在自动驾驶系统和先进的空间分析中,目标检测方法的不断演进至关重要。3D LiDAR目标检测作为一种变革性的技术,在环境感知方面提供了前所未有的准确性和深度信息. 在这里&…...
Kivy App开发之UX控件DropDown下拉列表
怎样在kivy中实现下拉列表的功能? 在kivy中,下拉列表的定位是自动的,即列表展开的位置根据上下方是否有控件自动调整,且可以包含其他控件,如按钮,图片等。 在应用中,需要使用base包下的runTouchApp类,用于触发下拉框。 DropDown控件常见的属性如下 属性相关说明auto_…...
机器学习模型评估指标
模型的评估指标是衡量一个模型应用于对应任务的契合程度,常见的指标有: 准确率(Accuracy): 正确预测的样本数占总样本数的比例。适用于类别分布均衡的数据集。 精确率(Precision): 在所有被预测为正类的样…...
C# 特性
总目录 C# 语法总目录 C# 特性 特性1. 特性类自定义格式2. 特性的位置参数和命名参数3. 特性的目标4. 指定多个特性5. 调用者信息特性 特性 1. 特性类自定义格式 自定义特性类需要继承自Attribute类,特性使用通常都会省略名字后面的Attribute,会自动识…...
Reactor测试框架之StepVerifier
Reactor测试框架之StepVerifier 测试步骤1、创建StepVerifier实例2、添加断言3、执行验证 代码实例 在响应式编程中,Reactor框架提供了StepVerifier测试类,用于对响应式序列进行断言和验证。StepVerifier主要用于对Publisher发出的元素序列进行逐步的、精…...
k8s helm部署kafka集群(KRaft模式)——筑梦之路
添加helm仓库 helm repo add bitnami "https://helm-charts.itboon.top/bitnami" --force-update helm repo add grafana "https://helm-charts.itboon.top/grafana" --force-update helm repo add prometheus-community "https://helm-charts.itboo…...
unity action委托举例
using System; using UnityEngine; public class DelegateExample : MonoBehaviour { void Start() { // 创建委托实例并添加方法 Action myAction Method1; myAction Method2; myAction Method3; // 调用委托,会依次执…...
conda 批量安装requirements.txt文件
conda 批量安装requirements.txt文件中包含的组件依赖 conda install --yes --file requirements.txt #这种执行方式,一遇到安装不上就整体停止不会继续下面的包安装。 下面这条命令能解决上面出现的不执行后续包的问题,需要在CMD窗口执行: 点…...
Flutter:封装一个自用的bottom_picker选择器
效果图:单列选择器 使用bottom_picker: ^2.9.0实现,单列选择器,官方文档 pubspec.yaml # 底部选择 bottom_picker: ^2.9.0picker_utils.dart AppTheme:自定义的颜色 TextWidget.body Text() <Widget>[].toRow Row()下边代…...
Group3r:一款针对活动目录组策略安全的漏洞检测工具
关于Group3r Group3r是一款针对活动目录组策略安全的漏洞检测工具,可以帮助广大安全研究人员迅速枚举目标AD组策略中的相关配置,并识别其中的潜在安全威胁。 Group3r专为红蓝队研究人员和渗透测试人员设计,该工具可以通过将 LDAP 与域控制器…...
支持向量机算法(一):像讲故事一样讲明白它的原理及实现奥秘
1、支持向量机算法介绍 支持向量机(Support Vector Machine,SVM)是一种基于统计学习理论的模式识别方法, 属于有监督学习模型,主要用于解决数据分类问题。SVM将每个样本数据表示为空间中的点,使不同类别的…...
力扣-数组-35 搜索插入位置
解析 时间复杂度要求,所以使用二分的思想,漏掉了很多问题,这里记录 在left-right1时,已经找到了插入位置,但是没有赋值,然后break,所以导致一直死循环。 if(right - left 1){result right;b…...
List ---- 模拟实现LIST功能的发现
目录 listlist概念 list 中的迭代器list迭代器知识const迭代器写法list访问自定义类型 附录代码 list list概念 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素…...
HashMap和HashTable区别问题
并发:hashMap线程不安全,hashTable线程安全,底层在put操作的方法上加了synchronized 初始化:hashTable初始容量为11,hashmap初始容量为16 阔容因子:阔容因子都是0.75 扩容比例: 补充 hashMap…...
mysql -> 达梦数据迁移(mbp大小写问题兼容)
安装 注意后面初始化需要忽略大小写 初始化程序启动路径 F:\dmdbms\tool dbca.exe 创建表空间,用户,模式 管理工具启动路径 F:\dmdbms\tool manager.exe 创建表空间 创建用户 创建同名模式,指定模式拥有者TEST dts 工具数据迁移 mysql -&g…...
leetcode热门100题1-4
第一天 两数之和 //暴力枚举 class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {int n nums.size();for (int i 0; i < n; i) {for (int j i 1; j < n; j) {if (nums[i] nums[j] target) {return {i, j};}}}return {…...
作业:IO:day2
题目一 第一步:创建一个 struct Student 类型的数组 arr[3],初始化该数组中3个学生的属性 第二步:编写一个叫做save的函数,功能为 将数组arr中的3个学生的所有信息,保存到文件中去,使用fread实现fwrite 第三步…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
Selenium 查找页面元素的方式
Selenium 查找页面元素的方式 Selenium 提供了多种方法来查找网页中的元素,以下是主要的定位方式: 基本定位方式 通过ID定位 driver.find_element(By.ID, "element_id")通过Name定位 driver.find_element(By.NAME, "element_name"…...
Qt学习及使用_第1部分_认识Qt---Qt开发基本流程
前言 学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面. 参考书:<Qt 6 C开发指南>(以下称"本书") 标识说明:概念用粗体倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字), 本书原话内容用深蓝色标识,比较重要的内容用加粗倾…...

