Leetcode刷题-字符串详细总结(Java)

news2024/10/7 16:18:38

字符串

字符串可能在算法处理上面和数组是类似的,但是String和数组的数据结构还是有一些不一样的

1、反转字符串

344. 反转字符串 - 力扣(LeetCode)

双指针的经典应用,两个指针同时向中间移动

public void reverseString(char[] s) {
    for(int i = 0,j = s.length - 1; i < s.length/2; i++,j--){
        char tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
}

2、反转字符串2

541. 反转字符串 II - 力扣(LeetCode)

在这里插入图片描述

  1. 这个题就是要求复杂一些,需要注意的就是不要上来用for循环就想着 i++。应该是i += 2k
  2. 每次只是反转i 到 i+k,可以单独写一个方法,注意一般编程语言中都是左闭右开的,所以是不包括 i+k的
  3. 但是需要有一个条件,if ( i+k < s.length ),不能超过数组长度了,这个if里判断的是最后剩余的部分是大于k的
  4. 如果不大于k的也需要被考虑到,所以在上面 if 的语句内需要加上一个continue
public String reverseStr(String s, int k) {
    char[] arr = s.toCharArray();				// 0.需要学会怎么将字符串转成数组
    for(int i = 0; i < arr.length; i += (2*k)){  // 1. 每隔 2k 个字符的前 k 个字符进行反转
        if(i + k <= arr.length){
            reverse(arr,i,i+k-1);  				// 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            continue;
        }
        reverse(arr,i,arr.length-1);  			// 3. 剩余字符少于 k 个,则将剩余字符全部反转
    }
    return new String(arr);
}
//对第i到第i+k进行反转
public void reverse(char[] s,int i,int j){
    for(int m = i,n = j; m < n; m++,n--){
        char tmp = s[m];
        s[m] = s[n];
        s[n] = tmp;
    }
}

3、翻转字符串⾥的单词(较为综合)

151. 反转字符串中的单词 - 力扣(LeetCode)

在这里插入图片描述

这个题复杂在,空格的位置是不确定的,单词的前面中间后面都可能有。但是我们最后的结果中不能包含额外空格

  1. 可以首先对整个字符串进行一次反转,这样单词的对应位置就是正确的了

  2. 之后再对每一个单词再进行单独的反转

  3. 需要注意的就是对空格的处理

    而对空格的处理,想到了之前总结数组部分中的,移动元素,这一个题,用双指针解决的问题

    但是在用双指针去移动元素的过程中,需要注意最后需要重新获取我们需要的部分,只要0-slow部分

class Solution {
    public String reverseWords(String s) {
        // 1.去除首尾以及中间多余空格
        char[] arr = s.toCharArray();
        arr = removeSpace(arr);
        // 2.反转整个字符串
        reverseString(arr, 0, arr.length - 1);
        // 3.反转各个单词
        reverseEachWord(arr);
        return new String(arr);    
    }

    //用 快慢指针 去除首尾以及中间多余空格,可参考数组元素移除的题解
    private char[] removeSpace(char[] arr) {
        int slow = 0;
        for(int fast = 0; fast < arr.length; fast++){
            if(arr[fast] != ' '){   //遇到非空格就处理,即删除所有空格。
                if(slow != 0)     //手动控制空格,给单词之间添加空格 slow != 0说明不是第一个单词,需要单词前添加空格
                    arr[slow++] = ' '; 
                while(fast < arr.length && arr[fast] != ' ')
                    arr[slow++] = arr[fast++];
            }
        }
        //这里需要注意的是,最后需要重新获取我们需要的部分,只要0-slow部分
        char[] newChars = new char[slow];
        System.arraycopy(arr, 0, newChars, 0, slow);
        return newChars;
    }

    //双指针实现指定范围内字符串反转
    public void reverseString(char[] arr, int start, int end) {
        while (start < end) {
            char tmp = arr[start];
            arr[start] = arr[end];
            arr[end] = tmp;
            start++;
            end--;
        }
    }

    //单词反转
    private void reverseEachWord(char[] arr) {
        int start = 0;
        //end <= s.length() 这里的 = ,是为了让 end 永远指向单词末尾后一个位置,这样 reverse 的实参更好设置
        for (int end = 0; end <= arr.length; end++) {
            // end 每次到单词末尾后的空格或串尾,开始反转单词
            if (end == arr.length || arr[end] == ' ') {
                reverseString(arr, start, end - 1);
                start = end + 1;
            }
        }
    }

}

4、KMP

目标是对目标文本串进行模式匹配,给定一个文本串和一个模式串,去寻找文本串中有无模式串出现

这里的关键是找到模式串的最长相等前后缀

模式串:aabaaf

那么a:0、aa:1、aab:0、aaba:1、aabaa:2、aabaaf:0

在这里插入图片描述

所以如果模式串aabaaf 的next数组,就是[0,1,0,1,2,0]

这就说明比如在匹配到模式串5位置,如果不匹配,就需要按照前面一个字符的next数组元素值,去跳到模式串的序号2的位置接替f位置

next数组构造过程

  • 需要两个指针:i 指向后缀末尾位置;j 指向前缀末尾位置,同时代表最长相等的前后缀长度

  • 首先初始化:

    1. 让 j = 0,此时next[0] = 0。j直接初始化为0,是因为它是前缀的一个末尾
    2. 而 i 的初始化是放在for循环中,for(int i = 1;i<长度;i++)
  • 如果i 和 j 不相等,那就需要让j 进行回退,是看它前一位的next数组元组,其实也就是类似在实际匹配过程中使用next数组一样

    但是不能一直回退,前提是j > 0

    回退是一个连续的过程,所以“前提是j > 0”,这个是while中,不是if中

  • 如果i 和 j 相等,让j++,同时更新next数组值,next[i] = j

private void getNext(int[] next, String s) {
    int j = 0;
    next[0] = 0;
    for (int i = 1; i < s.length(); i++) {
        while (j > 0 && s.charAt(j) != s.charAt(i)) 
            j = next[j - 1];
        if (s.charAt(j) == s.charAt(i)) 
            j++;
        next[i] = j; 
    }
}

整体代码:

class Solution {
    //前缀表(不减一)Java实现
    public int strStr(String haystack, String needle) {
        if (needle.length() == 0) return 0;
        int[] next = new int[needle.length()];
        getNext(next, needle);

        int j = 0;
        for (int i = 0; i < haystack.length(); i++) {
            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) 
                j = next[j - 1];
            if (needle.charAt(j) == haystack.charAt(i)) 
                j++;
            if (j == needle.length()) 
                return i - needle.length() + 1;
        }
        return -1;
    }
    
    private void getNext(int[] next, String s) {
        int j = 0;
        next[0] = 0;
        for (int i = 1; i < s.length(); i++) {
            while (j > 0 && s.charAt(j) != s.charAt(i)) 
                j = next[j - 1];
            if (s.charAt(j) == s.charAt(i)) 
                j++;
            next[i] = j; 
        }
    }
}

5、重复的子字符串

459. 重复的子字符串 - 力扣(LeetCode)

在这里插入图片描述

有两种思路:

  1. 比较巧的思路是,如果两个相同字符串s拼接起来,并移除第一个和最后一个字符。如果 s 是该字符串的子串,那么 s 就满足题目要求。[这个是可以证明的,不过比较难理解]

    ​ 下面代码的含义是:检查字符串 s 在自身重复连接后(即 s + s)中,从第二个 s 开始的位置是否不等于 s 字符串的长度。如果不相等,则返回 true,否则返回 false

    class Solution {
        public boolean repeatedSubstringPattern(String s) {
            return (s + s).indexOf(s, 1) != s.length(); //从索引位置 1 开始搜索。搜索第一个 s 出现的位置。这意味着它将忽略新字符串的第一个字符,从第二个字符开始搜索。如果在去除掉首元素后,去查找有无s这个子串,查找到的的起始位置是s.length(),那就说明这个是只能在后面拼接上的那个s匹配上,并不能靠中间部分匹配上
        }
    }
    
  2. 用kmp【这个方法暂时还未具体实践】

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

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

相关文章

C语言进阶课程学习记录-第20课 - 链接过程简介

C语言进阶课程学习记录-第20课 - 链接过程简介 链接器静态链接实验-静态链接源代码生成目标文件打包生成静态库文件直接编译使用静态库编译 动态链接实验-动态链接源代码生成动态链接库文件直接编译使用动态链接库编译运行test.out删除dlib.so运行test.out 小结 本文学习自狄泰…

【算法】二分算法题

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 1. 704. 二分查找1.1 分析1.2 代码 2. 34. 在排序数组中查找元素的第一个和最后一个位置2.1 分析2.2 代码 3. 35. 搜索插入位置3.1 分析3.2 代码 4. 852. 山脉数组的峰顶索引4.1 分析4.2 代码 5. 153. 寻找旋转排序数组中…

nexus设置s3存储

问题 因为我的nexus是安装在EC2上面&#xff0c;需要利用s3的存储能力&#xff0c;为nexus提供存储服务。 步骤 准备s3桶 输入桶名&#xff0c;创建s3桶&#xff0c;如下图&#xff1a; 创建桶读写策略 具体内容如下&#xff1a; {"Version": "2012-10-1…

【数据分享】我国第七次人口普查的100m分辨率人口栅格数据(免费获取\tif格式\2020年)

人口空间分布数据是我们在各项研究中经常使用的数据。之前我们分享过来源于LandScan数据集的2000-2022年的1km精度的人口空间分布栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01; 相较于LandScan全球人口数据集&#xff0c;我国历次人口普查的数据对于…

AI服务平台replicate

Replicate是一个提供优秀AI模型和工具的平台&#xff0c;旨在帮助用户实现各种人工智能任务。该平台汇集了来自各个领域的顶尖模型&#xff0c;涵盖了文本到图像生成、语言模型、图像编辑、超分辨率等多个领域。用户可以通过Replicate平台快速获取和应用先进的模型&#xff0c;…

【C++】优先级队列(priority_queue)的用法与实现

目录 一、概念&#xff1a; 二、仿函数&#xff08;Functor&#xff09;&#xff1a; 概念&#xff1a; 应用&#xff1a; 三、底层实现&#xff1a; 基本操作&#xff1a; 完整代码&#xff1a; 测试示例&#xff1a; 一、概念&#xff1a; 优先级队列&#xff08;pri…

小白水平理解面试经典题目1431. Kids With the Greatest Number of Candies【Array类】

个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 1431. 拥有最多糖果的孩子 小白渣翻译 一…

蓝桥杯刷题-17-平方差-打表+数学⭐(⊙o⊙)

之前的题目:最大也就到2e5左右。1e9的数据范围就意味着&#xff0c;即使是O(n)的复杂度&#xff0c;也会超时。此时可以考虑使用数学方法进行解题。 ❗打表:利用电脑去找一些合法答案&#xff0c;然后在这些合法答案中找规律。 ⭐打表后找到的规律: (1)好像所有的奇数都是合法…

spikingjelly训练自己的网络---量化 --测试

第二个 但是我发现&#xff0c;都要反量化&#xff0c;因为pytorch是只能支持浮点数的。 https://blog.csdn.net/lai_cheng/article/details/118961420 Pytorch的量化大致分为三种&#xff1a;模型训练完毕后动态量化、模型训练完毕后静态量化、模型训练中开启量化&#xff0c;…

Java 解决 Process 执行命令行命令报【CreateProcess error=2, 系统找不到指定的文件。】错误问题

目录 问题 问题代码 解决方案 判断操作系统 问题 使用 Process 执行命令行命令时&#xff0c;报 CreateProcess error2, 系统找不到指定的文件。但明明指定的文件是存在的。而且这种错误只在 IDEA 中运行会报错&#xff0c;打包后直接 java -jar 运行就能正常运行&#xf…

国产DSP FT-M6678开发-中断开发

全局中断控制器&#xff08;CIC&#xff09; FT-M6678 芯片集成了众多的外设&#xff0c;这些外设都可产生中断事件源&#xff0c;这些中断事件如何被服务取决于用户的特殊应用。在FT-M6678 芯片中&#xff0c;EDMA 和CorePac 都能够为事件服务&#xff0c;为了最大限度的增加系…

vue3第十六节(keep-alive 内置组件)

keep-alive 1、目的 在使用组件时&#xff0c;有时我们需要将组件进行缓存&#xff0c;而不是重新渲染&#xff0c;用以提高性能&#xff0c;避免重复加载DOM&#xff0c;提升用户的体验&#xff1b; keep-alive 组件可以做到这一点&#xff0c;它允许你缓存组件实例&#xf…

家用洗地机哪个牌子好?四大热销机型推荐,值得推荐!

随着科技的进步&#xff0c;洗地机在日常生活中能够帮助人们省时省力地打扫卫生&#xff0c;但市面上出现了各种各样的洗地机&#xff0c;好坏参差不齐&#xff0c;选择一个好品牌的洗地机非常重要&#xff0c;因为它们有着可靠的质量保证。那市面上如此众多的洗地机品牌&#…

Python爬虫之分布式爬虫

分布式爬虫 1.详情介绍 分布式爬虫是指将一个爬虫任务分解成多个子任务&#xff0c;在多个机器上同时执行&#xff0c;从而加快数据的抓取速度和提高系统的可靠性和容错性的技术。 传统的爬虫是在单台机器上运行&#xff0c;一次只能处理一个URL&#xff0c;而分布式爬虫通过将…

关于阿里云centos系统下宝塔面板部署django/中pip install mysqlclient失败问题的大总结/阿里云使用oss长期访问凭证

python版本3.12.0 问题1 解决方案 sudo vim /etc/profile export MYSQLCLIENT_CFLAGS"-I/usr/include/mysql" export MYSQLCLIENT_LDFLAGS"-L/usr/lib64/mysql" Esc退出编辑模式 &#xff1a;wq退出并且保存 问题二 说是找不到 mysql.h头文件 CentOS ‘…

【Python】不会优雅的记日志,你又又Out了!!!

1. 引言 在日常开发中&#xff0c;大家经常使用 print 函数来调试我们写的的代码。然而&#xff0c;随着打印语句数量的增加&#xff0c;由于缺乏行号或函数名称&#xff0c;很难确定输出来自何处。而且随着print语句的增多&#xff0c;调试完代码删除这些信息的时候也比较麻烦…

【动态规划-线性dp】【蓝桥杯备考训练】:乌龟棋、最长上升子序列、最长公共子序列、松散子序列、最大上升子序列和【已更新完成】

目录 1、乌龟棋 2、最长上升子序列 3、最长公共子序列 4、松散子序列 5、最大上升子序列和 1、乌龟棋 小明过生日的时候&#xff0c;爸爸送给他一副乌龟棋当作礼物。 乌龟棋的棋盘只有一行&#xff0c;该行有 N 个格子&#xff0c;每个格子上一个分数&#xff08;非负整…

植物大战僵尸Python版,附带源码注解

目录 一、实现功能 二、安装环境要求 三、如何开始游戏 四、怎么玩 五、演示 六、部分源码注释 6.1main.py 6.2map.py 6.3Menubar.py 七、自定义 7.1plant.json 7.2zombie.json 一、实现功能 实施植物&#xff1a;向日葵、豌豆射手、壁桃、雪豆射手、樱桃炸弹、三…

笔记-Building Apps with the ABAP RESTful Application Programming Model-Week3

Week3 Unit 1: The Enhanced Business Scenario 本节介绍了将要练习的demo的业务场景,在前两周成果的基础上,也就是只读列表,也可以说是报表APP基础上启用了事务能力,也就是CURD以及自定义业务功能的能力,从创建基本的behavior definition,然后behavior definition proj…

老王讲IT:高级变量类型

IT老王&#xff1a;高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 (int) 浮点型&#xff08;float&#xff09; 布尔型&#xff08;bool&#xff09; 真 True 非 0 数 —— 非零…