算法分析-面试1-字符串

文章目录

  • 前言
  • 一、分类:看看就行了
  • 二、字符串
    • API:
      • 创建和初始化:
      • 查询操作:
      • 比较操作:
      • 修改操作:
      • 截取操作:
      • 分割操作:
      • 格式化操作:
      • 连接操作(Java 8 及以后):
      • 构建和操作可变字符串(StringBuilder 和 StringBuffer):
      • 正则补充:
    • 力扣题CASE:
      • 1、密码匹配:
      • 2、字符串翻转
      • 3、寻找最长回文字串---其实使用类似暴力穷举法挨个进行遍历
        • 分析
      • 方法2
      • 4、寻找最长递增子序列(集合或者数组中也会有)同上都是动态规划类似暴力穷举法
  • 总结


前言

提示:任重而道远:
算法:一个刷一段时间很有感觉,然后一段时间内不刷又忘了的一种面试工具。
但是重点还得理解其思想。


一、分类:看看就行了

提示:算法问题大致可以归为以下几大类,每一类都有其特定的特点和基本的解题思路。
1、数组和字符串:

  • 特点:涉及数组的遍历、操作、变换以及字符串的处理问题。
  • 解题思路:熟悉数组索引操作、双指针法、排序、动态规划、字符串匹配算法。

2、链表:

  • 特点:包括链表的创建、反转、合并、排序等操作。
  • 解题思路:掌握指针和递归技巧,学会追踪节点之间的关系。

3、树和图:

  • 特点:主要涉及数据结构中的树(如二叉树、二叉搜索树等)和图的相关算法。
  • 解题思路:了解树遍历(前序、中序、后序),学习图的表示、遍历(DFS、BFS)以及特定算法(如Dijkstra和A*搜索算法)。

4、动态规划:

  • 特点:考查如何把复杂问题拆解为简单子问题,以及如何利用过往计算结果降低时间复杂度。
  • 解题思路:理解状态表示和状态转移方程,从子问题的构建和解决入手,求解原问题。

5、排序和搜索:

  • 特点:包括各种排序算法和搜索技术的应用。
  • 解题思路:掌握基本排序算法(如快速排序、归并排序)和二分搜索算法。

6、贪心算法:

  • 特点:通过局部最优选择来寻求全局最优解的问题。
  • 解题思路:识别贪心能够得到全局最优解的问题特点,构造贪心策略得到解决方案。

7、数学和数字操作:

  • 特点:涉及数学计算、数字处理,如素数计算、幂运算、位操作等。
  • 解题思路:掌握数学运算性质和逻辑运算技巧,处理数学逻辑题目。

8、递归和回溯:

  • 特点:解决可以通过回朔尝试找到可能的解集合的问题,常见于排列组合和解谜游戏。
  • 解题思路:采取试错的思想,通过递归方式对可能的解进行遍历。

9、分而治之:

  • 特点:包括将大问题拆分为若干小问题,单独解决后再合并结果的算法策略。
  • 解题思路:理解并运用分治模板,通常结合递归实现问题的拆解和解决。

10、设计问题:

  • 特点:设计数据结构或算法来满足特定的性能要求。
  • 解题思路:结合实际问题需求,使用合适的数据结构,注意考虑时间和空间复杂度。

二、字符串

提示:具体使用-此篇仅仅描述字符串:其他在后续系列文章中逐渐补充 算法第一步:先背API:

理解:其实字符串也能看成一个集合或者是数组,所谓的操作无非也是对其的增删改查操作。

API:

创建和初始化:

  • 使用字面量(例如:String s = “Hello”;)
  • 使用new关键字(例如:String s = new String(“Hello”);)

查询操作:

  • length():返回字符串的长度。
  • charAt(int index):返回指定索引处的字符。
  • indexOf(String str):返回指定子字符串首次出现的索引。
  • lastIndexOf(String str):返回指定子字符串最后出现的索引。
  • startsWith(String prefix):测试字符串是否以指定的前缀开始。
  • endsWith(String suffix):测试字符串是否以指定的后缀结束。
  • contains(CharSequence s):检查字符串中是否包含指定序列。

比较操作:

  • equals(Object obj):比较字符串与对象内容是否相等。
  • equalsIgnoreCase(String anotherString):与equals方法类似,但忽略大小写。
  • compareTo(String anotherString):按字典顺序比较两个字符串。

修改操作:

  • concat(String str):将指定字符串连接到此字符串的末尾。
  • replace(char oldChar, char newChar):返回一个新字符串,它是通过用newChar替换此字符串中出现的所有oldChar得到的。
  • replaceAll(String regex, String replacement):使用给定的replacement替换此字符串所有匹配给定的正则表达式的子字符串。
  • toUpperCase():返回一个新字符串,它是通过将此字符串中的所有字符转换为大写来创建的。
  • toLowerCase():返回一个新字符串,它是通过将此字符串中的所有字符转换为小写来创建的。
  • trim():返回一个新字符串,它去除了原始字符串头尾空白符。

截取操作:

  • substring(int beginIndex):返回一个新字符串,它是此原始字符串的一个子字符串。
  • substring(int beginIndex, int endIndex):返回一个新字符串,它是此原始字符串的一个子字符串,从beginIndex开始到endIndex结束。

分割操作:

  • split(String regex):根据匹配给定正则表达式的方式拆分字符串。

格式化操作:

  • String.format(String format, Object… args):返回一个使用指定语言环境、格式字符串和参数格式化的新字符串。
    转换操作:

  • getBytes():使用平台的默认字符集将此 String 编码为字节序列,并将结果存储到一个新的字节数组中。

  • toCharArray():将此字符串转换为一个新的字符数组。

连接操作(Java 8 及以后):

  • String.join(CharSequence delimiter, CharSequence… elements):返回一个新的字符串,通过使用指定的分隔符连接传入的元素。

构建和操作可变字符串(StringBuilder 和 StringBuffer):

  • StringBuilder 或 StringBuffer 的 append(), insert(), delete(), reverse() 等方法,它们提供了一种改变字符串内容的方式,而不产生新的字符串对象。

对于字符串操作,重要的是可读性和效率的平衡。对于简单的操作,直接使用String类的方法即可。
但是,如果需要在循环中或者在多次连续修改字符串时,建议使用StringBuilder或StringBuffer,因为它们是可变的,而String的每次修改都会生成新的字符串对象,可能导致内存和性能的开销。

正则补充:

1、使用replaceAll方法删除所有非字母字符,用空格替换。

String s = "$bo*y gi!r#l";
s = s.replaceAll("[^a-zA-Z]", " ");

2、 使用正则表达式 \\s+匹配一个或多个空格字符来分割字符串。

String s = "bo y gi r l";
String[] words = s.split("\\s+");

3、正则表达式格式匹配 .matches();


String phoneNumber = "123-456-7890";
// 检查电话号码是否匹配特定的格式
boolean isValidPhoneNumber = phoneNumber.matches("\\d{3}-\\d{3}-\\d{4}");// 在这个例子中,正则表达式 \\d{3}-\\d{3}-\\d{4} 指定了电话号码的一种常见格式,
// 其中 \\d 表示数字,{3} 表示前面的字符(数字)恰好重复3次。整个表达式匹配的格式为:
// 三位数字,一个破折号,三位数字,一个破折号,再后面是四位数字。String email = "example@email.com";
// 检查电子邮箱是否符合基本的电子邮箱格式
boolean isValidEmail = email.matches("[\\w.-]+@[\\w.-]+\\.[a-z]{2,}");
// 这里的正则表达式 [\\w.-]+@[\\w.-]+\\.[a-z]{2,} 用来匹配电子邮箱地址,
// 其中 \\w 表示字母、数字或下划线,+ 表示前面的字符组合可以出现一次或多次,
// [a-z]{2,} 表示邮箱的顶级域至少有两个字母长。

力扣题CASE:

1、密码匹配:

public class PasswordChecker {public int passwordStrength(String password) {int count = 0; // 用于统计满足条件的正则表达式数量// 判断密码中是否包含至少一个小写字母if (password.matches(".*[a-z].*")) {count++;}// 判断密码中是否包含至少一个大写字母if (password.matches(".*[A-Z].*")) {count++;}// 判断密码中是否包含至少一个数字if (password.matches(".*\\d.*")) {count++;}// 判断密码中是否包含至少一个非字母数字字符,这里使用了 ^ 表示取反,// [^a-zA-Z0-9] 表示除了字母和数字之外的任意字符if (password.matches(".*[^a-zA-Z0-9].*")) {count++;}// 返回满足的条件数,可以通过这个数来判断密码的强度return count;}public static void main(String[] args) {PasswordChecker checker = new PasswordChecker();String password = "Password123!";int strength = checker.passwordStrength(password);System.out.println("Password strength: " + strength + " out of 4");}
}

2、字符串翻转

import java.util.*;public class Solution {public String reverseWords(String s) {// 使用replaceAll方法删除所有非字母字符,用空格替换。s = s.replaceAll("[^a-zA-Z]", " ");// 使用trim方法去除可能出现的前后空格。s = s.trim();// 使用正则表达式\\s+匹配一个或多个空格字符来分割字符串。String[] words = s.split("\\s+");// 使用StringBuilder构造反转后的字符串。StringBuilder reversed = new StringBuilder();// 从后向前遍历单词数组,倒序构造字符串。for (int i = words.length - 1; i >= 0; i--) {reversed.append(words[i]);// 在单词之间添加空格,除了最后一个单词外。if (i > 0) {reversed.append(" ");}}// 返回构造好的字符串。return reversed.toString();}public static void main(String[] args) {Solution solution = new Solution();String input1 = "I am a student";System.out.println(solution.reverseWords(input1)); // 输出:student a am IString input2 = "$bo*y gi!r#l";System.out.println(solution.reverseWords(input2)); // 输出:l r gi y bo}
}

3、寻找最长回文字串—其实使用类似暴力穷举法挨个进行遍历

public class Main {public static int longestPalindrome(String s) {if (s == null || s.length() == 0) {return 0;}int n = s.length();boolean[][] dp = new boolean[n][n];int maxLength = 1; // 最长回文串的初始长度,至少为1// 初始化动态规划表中的单个字符和相邻字符对应的值for (int i = 0; i < n; i++) {dp[i][i] = true; // 任何一个单独的字符都是回文串if (i < n - 1 && s.charAt(i) == s.charAt(i + 1)) {dp[i][i + 1] = true; // 相邻且字符相同的两个字符是回文串maxLength = 2;}}// 使用动态规划,从长度为3开始一直到字符串总长度for (int len = 3; len <= n; len++) {// i为开始位置for (int i = 0; i + len <= n; i++) {int j = i + len - 1; // j为结束位置// 如果开始和结束的字符相同,并且去掉两端的子字符串也是回文串if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]) {dp[i][j] = true; // 更新动态规划表,标记为回文串maxLength = len; // 更新最长回文子串的长度}}}return maxLength; // 返回找到的最长回文串的长度}public static void main(String[] args) {String input = "12HHHHA";System.out.println(longestPalindrome(input)); // 输出:4}
}
分析
  • 定义名为longestPalindrome的方法来找出最长有效密码串(即最长的回文子串)。
  • 首先检查输入字符串s是否为空或长度为0,如果是,则返回0。
  • 初始化字符串的长度n和一个二维布尔数组dp来保存动态规划的状态。dp[i][j]将会表示字符串从索引i到索引j之间的子串是否是回文串。
  • 然后,对于所有可能的起始点i到终点i + 1之间的情况,检查是否存在长度为2的回文串,并初始化动态规划表中对应项的值为true。
  • 接下来是动态规划的主循环,使用变量len从3开始迭代,直到字符串的总长度。对于每一个长度,检查所有可能的子字符串,更新动态规划表,并记录最长回文子串的长度。
  • 如果找到更长的回文子串,将maxLength更新为当前子串的长度。
  • 最终返回maxLength作为最长回文子串的长度。
  • main方法中创建一个输入的测试字符串,调用longestPalindrome方法,并输出结果。

方法2

public class Main2 {public static void main(String[] args) {String str = "12HHHHA";System.out.println("最长的回文子串长度是:" + longestPalindromeSubstringLength(str));}public static int longestPalindromeSubstringLength(String str) {int maxLength = 0; // 最长回文子串的长度for (int i = 0; i < str.length(); i++) {// 处理奇数长度的回文串maxLength = Math.max(maxLength, expandAroundCenter(str, i, i));// 处理偶数长度的回文串maxLength = Math.max(maxLength, expandAroundCenter(str, i, i + 1));}return maxLength;}/*** 从left和right指定的中心位置向外扩展,寻找最长的回文子串*/public static int expandAroundCenter(String s, int left, int right) {while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {left--;right++;}return right - left - 1; // 回文长度}
}

4、寻找最长递增子序列(集合或者数组中也会有)同上都是动态规划类似暴力穷举法

总结

其实还是对字符串的增删改查遍历(正序、倒序、修改后或者替换后再遍历),总的来讲这是最简单的,主要是得明确哪些API的作用是什么,以及正则表达式怎么用

欢迎交流:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

给大家分享一款小程序:AI一秒修图

AI一秒修图 照片修复的AI助手特点&#xff1a;Demo&#xff08;1.选择图片 2.涂抹遮罩 3.消除&#xff09;Product Roadmap (版本演进)Contact-联系我们Reference 照片修复的AI助手 照片修复小小助手是一款快速P图微信小程序&#xff0c;用来消除图片中指定的人和物&#xff…

人工智能绘画的时代下到底是谁在主导,是人类的想象力,还是AI的创造力?

#ai作画 目录 一.AI绘画的概念 1. 数据集准备&#xff1a; 2. 模型训练&#xff1a; 3. 生成绘画&#xff1a; 二.AI绘画的应用领域 三.AI绘画的发展 四.AI绘画背后的技术剖析 1.AI绘画的底层原理 2.主流模型的发展趋势 2.1VAE — 伊始之门 2.2GAN 2.2.1GAN相较于…

软考43-上午题-【数据库】-关系代数转SQL语言

一、投影转SQL语言-select 示例&#xff1a; 二、选择转SQL语言-where 示例&#xff1a; 【注意】&#xff1a; 关系代数公式的写法&#xff0c;可以写属性名&#xff0c;也可以写列的序号&#xff0c;如&#xff1a; 但是&#xff0c;SQL语言不支持&#xff01;&#xff01;&a…

软件设计师软考题目解析05 --每日五题

想说的话&#xff1a;要准备软考了。0.0&#xff0c;其实我是不想考的&#xff0c;但是吧&#xff0c;由于本人已经学完所有知识了&#xff0c;只是被学校的课程给锁在那里了&#xff0c;不然早找工作去了。寻思着反正也无聊&#xff0c;就考个证玩玩。 本人github地址&#xf…

H5多用途的产品介绍展示单页HTML5静态网页模板

H5多用途的产品介绍展示单页HTML5静态网页模板 源码介绍&#xff1a;一款H5自适应多用途的产品介绍展示单页HTML静态网页模板&#xff0c;可用于团队官网、产品官网。 下载地址&#xff1a; https://www.changyouzuhao.cn/13534.html

作业 找单身狗2

方法一&#xff1a; 思路&#xff1a; 我们可以先创建一个新的数组&#xff0c;初始化为0&#xff0c;然后让原来的数组里面的元素作为新数组的下标 如果该下标对应的值为0&#xff0c;说明没有出现过该数&#xff0c;赋值为1作为标记&#xff0c;表示出现过1次 如果该下标…

掌握BeautifulSoup4:爬虫解析器的基础与实战【第91篇—BeautifulSoup4】

掌握BeautifulSoup4&#xff1a;爬虫解析器的基础与实战 网络上的信息浩如烟海&#xff0c;而爬虫技术正是帮助我们从中获取有用信息的重要工具。在爬虫过程中&#xff0c;解析HTML页面是一个关键步骤&#xff0c;而BeautifulSoup4正是一款功能强大的解析器&#xff0c;能够轻…

Java8 Stream API 详解:流式编程进行数据处理

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&…

Go语言必知必会100问题-03 滥用init函数

滥用init函数 在Go语言中&#xff0c;滥用init函数会导致难以理解的代码流和槽糕的错误处理。本文将对init函数进行一个梳理&#xff0c;什么是init函数以及推荐的使用场景。 init函数 init函数是一个不带参数并且无返回结果的函数&#xff08;func()函数&#xff09;。初始…

[云原生] 二进制安装K8S(上)搭建单机matser、etcd集群和node节点

一、单机matser预部署设计 目前Kubernetes最新版本是v1.25&#xff0c;但大部分公司一般不会使用最新版本。 目前公司使用比较多的&#xff1a;老版本是v1.15&#xff0c;因为v1.16改变了很多API接口版本&#xff0c;国内目前使用比较多的是v1.18、v1.20。 组件部署&#xff…

【Linux】部署单机项目(自动化启动)

目录 一.jdk安装 二.tomcat安装 三.MySQL安装 四.部署项目 一.jdk安装 1.上传jdk安装包 jdk-8u151-linux-x64.tar.gz 进入opt目录&#xff0c;将安装包拖进去 2.解压安装包 防止后面单个系列解压操作&#xff0c;我这边就直接将所有的要用的全部给解压&#xff0c;如下图注…

Chiplet技术与汽车芯片(二)

目录 1.回顾 2.Chiplet的优势 2.1 提升芯片良率、降本增效 2.2 设计灵活&#xff0c;降低设计成本 2.3 标准实行&#xff0c;构建生态 3.Chiplet如何上车 1.回顾 上一篇&#xff0c;我们将来芯粒到底是什么东西&#xff0c;本篇我们来看芯粒技术的优势&#xff0c;以及它…

Django入门指南:从环境搭建到模型管理系统的完整教程

环境安装&#xff1a; ​ 由于我的C的Anaconda 是安装在C盘的&#xff0c;但是没内存了&#xff0c;所有我将环境转在e盘&#xff0c;下面的命令是创建环境到指定目录中. conda create --prefixE:\envs\dj42 python3.9进入环境中&#xff1a; conda activate E:\envs\dj42…

多线程相关(4)

线程安全-下 使用层面锁优化减少锁的时间&#xff1a;减少锁的粒度&#xff1a;锁粗化&#xff1a;使用读写锁&#xff1a;使用CAS&#xff1a; 系统层面锁优化自适应自旋锁锁消除锁升级偏向锁轻量级锁重量级锁 ThreadLocal原理ThreadLocal简介原理ThreadLocal内存泄漏 HashMap…

go interface{} 和string的转换问题

1.遇到的问题 问题来源于,我sql模版拼接遇到的问题。 首先&#xff0c;这样是没有问题的。 var qhx interface{} "qhx"s : qhx.(string)fmt.Println(s) 但是当我在这段代码里用:1.类型断言 var sqlStr "select * from tx_user where username %s" join…

代码随想录算法训练营第二十五天 | 216.组合总和III,17.电话号码的字母组合 [回溯篇]

代码随想录算法训练营第二十五天 LeetCode 216.组合总和III题目描述思路参考代码总结 LeetCode 17.电话号码的字母组合题目描述思路参考代码 LeetCode 216.组合总和III 题目链接&#xff1a;216.组合总和III 文章讲解&#xff1a;代码随想录#216.组合总和III 视频讲解&#xff…

opengl 学习纹理

一.纹理是什么&#xff1f; 纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c;它可以用来添加物体的细节&#xff1b;类似于图像一样&#xff0c;纹理也可以被用来储存大量的数据&#xff0c;这些数据可以发送到着色器上。 采样是指用纹理坐标来获取纹…

医学试纸条图像处理技术

医学试纸条图像处理是一个重要的领域&#xff0c;它涉及到从医学试纸条上提取和分析信息的各种技术。这里是一些常见的工作步骤&#xff1a; 一、图像预处理&#xff1a;在处理任何图像之前&#xff0c;通常需要进行预处理步骤&#xff0c;以改善图像质量并准备后续分析。这可…

VH6501采样点测试误差及影响因素分析(官方文档)

&#x1f4d9; 相关文章 &#x1f345; 我是蚂蚁小兵&#xff0c;专注于车载诊断领域&#xff0c;尤其擅长于对CANoe工具的使用&#x1f345; 寻找组织 &#xff0c;答疑解惑&#xff0c;摸鱼聊天&#xff0c;博客源码&#xff0c;点击加入&#x1f449;【相亲相爱一家人】&…

挑战杯 基于情感分析的网络舆情热点分析系统

文章目录 0 前言1 课题背景2 数据处理3 文本情感分析3.1 情感分析-词库搭建3.2 文本情感分析实现3.3 建立情感倾向性分析模型 4 数据可视化工具4.1 django框架介绍4.2 ECharts 5 Django使用echarts进行可视化展示5.1 修改setting.py连接mysql数据库5.2 导入数据5.3 使用echarts…