算法分析-面试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 I

        String 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的作用是什么,以及正则表达式怎么用

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

静态时序分析:SDC约束命令set_load详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 set_load命令用于指定端口(port)或线网(net)的负载电容&#xff0c;该指令的BNF范式&#xff08;有关BNF范式&#xff0c;可以参考以往文章&#xff09;为&#…

JAVA毕业设计129—基于Java+Springboot+thymeleaf的物业管理系统(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootthymeleaf的物业管理系统(源代码数据库)129 一、系统介绍 本项目前后端分离&#xff0c;本系统分为管理员、小区管理员、用户三种角色 1、用户&#xff1a; 登…

基于Pytorch的猫狗图片分类【深度学习CNN】

猫狗分类来源于Kaggle上的一个入门竞赛——Dogs vs Cats。为了加深对CNN的理解&#xff0c;基于Pytorch复现了LeNet,AlexNet,ResNet等经典CNN模型&#xff0c;源代码放在GitHub上&#xff0c;地址传送点击此处。项目大纲如下&#xff1a; 文章目录 一、问题描述二、数据集处理…

【GPTs分享】GPTs分享之Write For Me

Write For Me 是一个专门定制的GPT版本&#xff0c;旨在为用户提供高质量的文本内容创作服务。它适用于各种写作需求&#xff0c;从商业计划、学术文章到创意故事等。下面是从简介、主要功能、使用案例、优点和局限性几个方面对Write For Me 的详细介绍。 简介 Write For Me …

MySQL-主从复制

目录 1. 主从复制概述 1.1 如何提升数据库并发能力 1.2 主从复制的作用 2. 主从复制的原理 2.1 原理剖析 三个线程 复制三步骤 复制的问题 2.2 复制的基本原则 3. 一主一从架构搭建 3.1 准备工作 3.2 主机配置文件 3.3 从机配置文件 3.4 主机&#xff1a;建立账户…

每日五道java面试题之spring篇(六)

目录&#xff1a; 第一题 ApplicationContext通常的实现是什么&#xff1f;第二题 什么是Spring的依赖注入&#xff1f;第三题 依赖注入的基本原则第四题 依赖注入有什么优势&#xff1f;第五题 有哪些不同类型的依赖注入实现方式&#xff1f; 第一题 ApplicationContext通常的…

【hashmap】【将排序之后的字符串作为哈希表的键】【获取 HashMap 中所有值的集合】Leetcode 49 字母异位词分组

【hashmap】【将排序之后的字符串作为哈希表的键】【获取 HashMap 中所有值的集合】Leetcode 49 字母异位词分组 解法1 将排序之后的字符串作为哈希表的键解法2 在解法一的基础上加入了getOrDefault ---------------&#x1f388;&#x1f388;题目链接&#x1f388;&#x1f3…

groovy:XmlParser 读 Freeplane.mm文件,生成测试案例.csv文件

Freeplane 是一款基于 Java 的开源软件&#xff0c;继承 Freemind 的思维导图工具软件&#xff0c;它扩展了知识管理功能&#xff0c;在 Freemind 上增加了一些额外的功能&#xff0c;比如数学公式、节点属性面板等。 强大的节点功能&#xff0c;不仅仅节点的种类很多&#xff…

【管理咨询宝藏资料25】某能源集团五年发展战略报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏资料25】某能源集团五年发展战略报告 【关键词】战略规划、五年战略、管理咨询 【文件核心观点】 - LL应以快速做大做强为目标&#xff0c;专注…

CleanMyMac X2024告别硬盘空间不足,让您的Mac电脑极速如新

CleanMyMac X支持多种操作系统版本&#xff0c;包括macOS 10.10&#xff08;Yosemite&#xff09;、macOS 10.11&#xff08;El Capitan&#xff09;、macOS 10.12&#xff08;Sierra&#xff09;、macOS 10.13&#xff08;High Sierra&#xff09;、macOS 10.14&#xff08;Mo…

查看笔记本电池健康状态-windows11

在 Windows 11 中获取详细的电池报告 Windows 11 中内置的 Powerfg 命令行选项来生成电池报告。 在任务栏上选择“搜索”&#xff0c;键入“cmd”&#xff0c;长按&#xff08;或右键单击&#xff09;“命令提示符”&#xff0c;然后选择“以管理员身份运行” ->“是”。 …

AI赋能Oracle DBA:以自然语言与Oracle数据库互动

DBA AI助手&#xff1a;以自然语言与Oracle数据库互动 0. 引言1. AI赋能Oracle DBA的优势2. AI如何与Oracle数据库交互3. 自然语言查询的一些示例4. 未来展望 0. 引言 传统的Oracle数据库管理 (DBA) 依赖于人工操作&#xff0c;包括编写复杂的SQL语句、分析性能指标和解决各种…

Unity(第五部)新手图层和标签的理解

1、标记用于在物体上显示名字&#xff0c;方便开发 2、标签&#xff08;某一类物体&#xff0c;方便给某一类进行组件脚本编写&#xff09; 而且有了标签之后&#xff0c;我们在写代码的时候就可以直接通过标签找到一系列我们需要的游戏物体了 Untagged未标记Respawn重生Edi…

力扣随笔之移除元素(简单27)

思路&#xff1a;定义一个指针left&#xff0c;使该指针及该指针左边的数全部都不等于val&#xff0c;定义一个遍历指针i&#xff0c;若nums[i] val&#xff0c;则i自加&#xff0c;若nums[i] ! val&#xff0c;则将left&#xff0c;并将nums[i]的值赋给nums[left]&#xff0c…

YOLO算法改进Backbone系列之:EfficientViT

EfficientViT: Memory Effificient Vision Transformer with Cascaded Group Attention 摘要&#xff1a;视觉transformer由于其高模型能力而取得了巨大的成功。然而&#xff0c;它们卓越的性能伴随着沉重的计算成本&#xff0c;这使得它们不适合实时应用。在这篇论文中&#x…

LeetCode_Java_环形链表(题目+思路+代码)

141.环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位…

图像的压缩感知的MATLAB实现(第3种方案)

前面介绍了两种不同的压缩感知实现&#xff1a; 图像压缩感知的MATLAB实现&#xff08;OMP&#xff09; 压缩感知的图像仿真&#xff08;MATLAB源代码&#xff09; 上述两种方法还存在着“速度慢、精度低”等不足。 本篇介绍一种新的方法。 压缩感知&#xff08;Compressed S…

【Django开发】0到1开发美多shop项目:用户登录模块开发。全md文档笔记(附代码 文档)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论django商城项目相关知识。项目利用Django框架开发一套前后端不分离的商城项目&#xff08;4.0版本&#xff09;含代码和文档。功能包括前后端不分离&#xff0c;方便SEO。采用Django Jinja2模板引擎 Vue.js实现前后端…

(202402)多智能体MetaGPT入门1:MetaGPT环境配置

文章目录 前言拉取MetaGPT仓库1 仅仅安装最新版2 拉取源码本地安装MetaGPT安装成果全流程展示 尝试简单使用1 本地部署大模型尝试&#xff08;失败-->成功&#xff09;2 讯飞星火API调用 前言 感谢datawhale组织开源的多智能体学习内容&#xff0c;飞书文档地址在https://d…

《Docker 简易速速上手小册》第9章 Docker 与持续集成(2024 最新版)

文章目录 9.1 持续集成的基本概念9.1.1 重点基础知识9.1.2 重点案例&#xff1a;Python Web 应用的 CI 流程9.1.3 拓展案例 1&#xff1a;Python 数据分析项目的 CI9.1.4 拓展案例 2&#xff1a;Python 微服务的 CI/CD 9.2 Docker 在 CI/CD 中的应用9.2.1 重点基础知识9.2.2 重…