leetcode字符串刷题总结

Leetcode刷题方法总结---字符串全解 阅读详情

一、KMP算法 ****

1. 理论

  • 主要思想
    当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。
    next数组
  • next数组和前缀表
    针对模式串而言
    next数组既可以就是前缀表,也可以是前缀表统一减一(右移一位,初始位置为-1)。
  • 核心概念
    前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串
    模式串与前缀表对应位置的数字表示的就是: 下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。
    在这里插入图片描述
  • 做题思路 两部曲
    对模式串求next数组(难点):双指针,一个指向后缀的最后一个元素,一个指向前缀的最后一个元素
    利用数组来优化,再文本串中找模式串
  • 如何利用 前缀表找到 当字符不匹配的时候应该指针应该移动的位置
    找到的不匹配的位置, 那么此时我们要看它的前一个字符的前缀表的数值是多少。
    宫水三叶解释

T459. 重复的子字符串(用next数组的特点求解)

在这里插入图片描述
假设字符串s使用多个重复子串构成(这个子串是最小重复单位),重复出现的子字符串长度是x,所以s是由n * x组成。

因为字符串s的最长相同前后缀的长度一定是不包含s本身,所以 最长相同前后缀长度必然是m * x,而且 n - m = 1,
如果len % (len - (next[len - 1] + 1)) == 0 ,则说明数组的长度正好可以被 (数组长度-最长相等前后缀的长度) 整除 ,说明该字符串有重复的子字符串。

数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。

class Solution {
    //kmp算法:利用next数组
    public boolean repeatedSubstringPattern(String s) {
        int len = s.length();
        int[] next = new int[len];
        next[0] = 0;
        int j = 0;//指向前缀的最后一个元素
        for(int i=1;i<len;i++){//i指向后缀的最后一个元素
            while(j>0&&s.charAt(i) != s.charAt(j)){//不同,j指针不断往回
                j = next[j-1];
            }
            if(s.charAt(i) == s.charAt(j)){//相同
                j++;
            }
            next[i] = j;
        }
        if(len%(len-next[len-1])==0 && next[len-1]>0){
            return true;
        }
        return false;
    }
}

T28. 找出字符串中第一个匹配项的下标

在这里插入图片描述
时间复杂度:o(m+n)

class Solution {
    //kmp算法
    //称haystack为文本串;needle为模式串
    public int strStr(String haystack, String needle) {
        int[] next = getNext(needle);//由模式串获得next数组
        //遍历文本串,只需要遍历1次,i递增
        //遍历模式串,j不是递增的
        int j = 0;
        for(int i = 0;i<haystack.length();i++){
            while(j>0 && needle.charAt(j) != haystack.charAt(i)){//文本串和模式串不匹配
                j = next[j-1];//j不需要从头遍历 可以根据next跳转
            }
            if(haystack.charAt(i) == needle.charAt(j)){
                j++;
            }
            if(j == needle.length()){
                return i-needle.length()+1;
            }
        }
        return -1;
    }
    //找出模式串的next数组
    //next表示记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀
    public int[] getNext(String needle){
        //初始化
        int j = 0;
        int[] next = new int[needle.length()];
        next[0] = 0;
        //从1开始遍历
        for(int i = 1;i<needle.length();i++){
            while(j>0 && needle.charAt(i) != needle.charAt(j)){
                j = next[j-1];//字符不相等. 难点1
            }
            if(needle.charAt(i) == needle.charAt(j)){
                j++;
            }
            next[i] = j;
        }
        return next;
    }
}

二. 反转旋转系列

T541. 反转字符串Ⅱ (分段反转字符,字符数组)

在这里插入图片描述

class Solution {
    public String reverseStr(String s, int k) {
        char[] sc = s.toCharArray();
        for(int i=0;i<s.length();i+=2*k){
            int start = i;
            int end = Math.min(start+k-1,s.length());
            while(start<end){
                char temp = sc[end];
                sc[end] = sc[start];
                sc[start] = temp;
                start++;
                end--;
            }
        }
        return new String(sc);
    }
}

剑指Offer 05.替换空格 (StringBuilder)

在这里插入图片描述

class Solution {
    public String replaceSpace(String s) {
        if(s.length()==0) return "";
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)==' '){
                sb.append("%20");
            }else{
                sb.append(s.charAt(i));
            }
        }
        return sb.toString();
    }
}

T151. 反转字符串中的单词(翻转字符+移除空格) ***

在这里插入图片描述

class Solution {
    public String reverseWords(String s) {
        //1.删除空格
        //2.翻转整个字符串
        //3.翻转单词
        String sb  = removeSpace(s);
        int start = 0;
        int end = sb.length() - 1;
        String reverseStr = reverseStr(sb,start,end);
        String str = reverseWord(reverseStr);
        return str;
    }

    //1.移除空格
    public String removeSpace(String s){
        StringBuilder sb = new StringBuilder();
        int start = 0;
        int end = s.length()-1;
        //移除开头和结尾的空格
        while(s.charAt(start) == ' ') {start++;}
        while(s.charAt(end) == ' '){ end--;}
        while(start<=end){
            char c = s.charAt(start);
            //c不为空格
            //c为空格但是sb字符串的最后一个字符不是空格
            if(c != ' ' || sb.charAt(sb.length()-1) != ' '){
                sb.append(c);
            }
            start++;
        }
        return sb.toString();
       }
    //2.翻转字符串
    public String reverseStr(String s, int start, int end){
        char[] schar = s.toCharArray();
        while (start<end){
            char temp = schar[start];
            schar[start] = schar[end];
            schar[end] = temp;
            start++;
            end--;
        }
        return new String(schar);
    }
    public String reverseWord(String s){
        //从前开始遍历,遇到空格和到达结尾就翻转字符串s
        int start = 0;
        int end = 1;
        int len = s.length();
        String sb = s;
        while(start<len){
            while(end<len && s.charAt(end) != ' '){
                end++;
            }
            sb = reverseStr(sb,start,end-1);
            start = end+1;
            end = start+1;
        }
        return sb;
    }
}

剑指 Offer 58 - II. 左旋转字符串(附加要求:不能申请额外空间,只能在本串上操作)

在这里插入图片描述

class Solution {
    //不用额外空间
    public String reverseLeftWords(String s, int n) {
        char[] sc = s.toCharArray();
        //翻转前n个
        reverseHelp(sc,0,n-1);
        //翻转n到 len个
        reverseHelp(sc,n,sc.length-1);
        //整体翻转
        reverseHelp(sc,0,sc.length-1);
        return new String(sc);
    }
    public void reverseHelp(char[] s, int start, int end){
        while(start<end){
            char temp = s[start];
            s[start] = s[end];
            s[end] = temp;
            start++;
            end--;
        }
    }
}
class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n) + s.substring(0,n);
    }
}

三. 括号问题

T678. 有效的括号字符串(栈模拟 / dp)

在这里插入图片描述
两个栈模拟
两个栈存放索引,方便后续左括号和*号进行比较

class Solution {
    public boolean checkValidString(String s) {
        Deque<Integer> leftStack = new LinkedList<>();//放的是索引,方便后续判断
        Deque<Integer> star = new LinkedList<>();
        //遇到左括号和*号入栈,遇到右括号先判断左括号,再判断*号
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            if(c == '('){
                leftStack.push(i);
            }else if(c == '*'){
                star.push(i);
            }else if(c == ')'){
                if(!leftStack.isEmpty()){
                    leftStack.pop();
                }else if(!star.isEmpty()){
                    star.pop();
                }else {
                    return false;
                }
            }
        }
        //处理左括号和*
        //要左和*匹配,则左的索引必须小于*的索引
        while(!leftStack.isEmpty() && !star.isEmpty()){
            int leftIndex = leftStack.pop();
            int starIndex = star.pop();
            if(leftIndex>starIndex){
                return false;
            }
        }
        return leftStack.isEmpty();
    }
}

T20. 有效的括号

T22. 括号生成

T32. 最长有效括号

T301. 删除无效的括号

0. 面试真题

T394.字符串解码(栈+字符串) *** 华为

在这里插入图片描述

class Solution {
    //辅助栈+模拟
    public String decodeString(String s) {
        StringBuilder res = new StringBuilder();
        int num = 0;//用来记录遍历到的数字,因为要乘10处理
        Deque<Integer> stackInt = new LinkedList<>();
        Deque<String> stackStr = new LinkedList<>();//辅助栈:保存处理好的str

        for(Character c:s.toCharArray()){
            if(c == '['){//数字和字母都入栈
                stackStr.push(res.toString());//把之前处理好的字符入栈
                stackInt.push(num);
                num = 0;//清空数字
                res = new StringBuilder();//清空字符
            }else if(c == ']'){
                int multi = stackInt.pop();//取出要乘的倍数
                StringBuilder temp = new StringBuilder();
                for(int i =0;i<multi;i++){
                    temp.append(res);
                }
                res = new StringBuilder(stackStr.pop()+temp);
            }else if(c >='0' && c<='9'){
                num = num*10 + Integer.parseInt(String.valueOf(c));
            }else{
                res.append(c);
            }
        }
        return res.toString();

    }
}

压缩算法:腾讯,与上一题类似 ***

在这里插入图片描述

import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;

public class Main{
    public static  void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        StringBuilder res = new StringBuilder();
        int num = 0;
        Deque<Integer> stackNum = new LinkedList<>();
        Deque<String> stackStr = new LinkedList<>();
        for (char c : line.toCharArray()) {
            if(c == '['){
                stackStr.push(res.toString());
                res = new StringBuilder();
            }else if(c == '|'){
                stackNum.push(num);
                num=0;
            }else if(c >= '0' && c <= '9'){
                num = num*10 + c - '0';
            }else if(c == ']'){
                int multi = stackNum.pop();
                StringBuilder sb = new StringBuilder();
                for(int i=0;i<multi;i++){
                    sb.append(res);
                }
                res = new StringBuilder(stackStr.pop() + sb);
            }else{
                res.append(c);
            }
        }
        System.out.println(res.toString());

    }
}

华为 HJ27 查找兄弟单词

在这里插入图片描述

import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String[] wordSet = new String[n];
        for (int i = 0; i < n; i++) {
            wordSet[i] = in.next();
        }
        String target = in.next();
        int m = in.nextInt();
        int len = target.length();
        int count = 0;
        List<String> res = new ArrayList<>();
        char[] tempTarget = target.toCharArray();
        Arrays.sort(tempTarget);
        for (int i = 0; i < n; i++) {
            if (wordSet[i].length() != len || target.compareTo(wordSet[i]) == 0) {
                continue;
            }
            char[] temp = wordSet[i].toCharArray();
            Arrays.sort(temp);
            Arrays.sort(tempTarget);
            String str = String.valueOf(temp);
            if (str.equals(String.valueOf(tempTarget))) {
                count++;
                res.add(wordSet[i]);
            }
        }
        System.out.println(count);
        if(m<res.size()){
            Collections.sort(res);
            System.out.println(res.get(m-1));
        }
    }
}

虚拟电厂功率预测最佳实践白皮书 虚拟电厂(VPP)通过聚合分散的可再生能源资源,为电网提供可观测、可调度和可交易的解决方案。本文提出了一套功率预测方法论,并给出LSTM实现脚本,涵盖资源接入、数据治理、预测模型设计及市场交易闭环。针对风-光-储-负荷混合场景,该方法论强调轻量化部署和滚动优化,可有效提升预测精度和调度收益。未来研究将融合深度气象预报和强化学习,进一步优化VPP的协同调度能力。 阅读详情

相关推荐

[附源码]计算机毕业设计JAVA网上花店系统

附源码]计算机毕业设计JAVA网上花店系统项目运行环境配置:(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;3.tomcat。

ssm毕设程序设计 2443

力扣(leetcode)题目总结——字符串篇

本系列文章初衷是为了按类别整理出力扣(leetcode)最经典题目,一共100多道题,每道题都给出了非常详细的解题思路、算法步骤、代码实现。因为力扣题目顺序是随机的,并没有按照算法分类,导致同一类型的算法强化训练不够。所以本系列文章就是来帮你完成算法分类,针对每种算法做强化训练,保证让你以后遇到题目直接秒杀。本篇文章主要是针对字符串相关的算法题,一次性帮你搞定所有字符串题!

weixin_46571171的博客 4778

第十九届全国大学生智能车竞赛越野信标 硬件篇

全国大学生智能汽车竞赛,越野信标组

2301_77568650的博客 4115

【LeetCode】字符串总结

65. 有效数字 思路: class Solution { public boolean isNumber(String s) { int n = s.length(); char[] cs = s.toCharArray(); int idx = -1; // 通过 e/E 对字符串进行分割 for (int i = 0; i < n; i++) {

flora 487

Linux音频处理实战:从MP3解码到ALSA播放的完整流程解析

本文详细解析了Linux环境下从MP3文件解码到通过ALSA播放音频的完整实战流程。文章深入剖析了MP3文件结构、PCM原始音频数据格式,并提供了使用ffmpeg/mpg123解码、以及利用ALSA库进行C语言编程播放的实用代码示例,帮助开发者彻底掌握Linux音频处理的核心链路。

weixin_29206669的博客 72

Underactuated Robotics - 欠驱动机器人学(一)- 全驱动与欠驱动系统

根据牛顿的观点,机械系统的动力学是二阶的(其状态由位置向量 q(也称为配置向量)和速度向量以及(可能还有)时间给出。二阶控制动力系统的一般形式是:其中 u 是控制向量。定义 1.1 (欠驱动控制微分方程) 二阶控制微分方程描述如下:在状态和时间 t 中,如果所得到的映射是可射的:对于每一个,都存在一个能产生预期响应的,那么系统就是全驱动的。否则,就是欠驱动(状态在时间 t)。

机器人控制与仿真应用 3377

LeetCode刷题小结---字符串篇

寄。

TheBug114514的博客 609

2023华为od机试C卷【最富裕的小家庭】C++ 实现

在一颗树中,每个节点代表一个家庭成员,节点的数字表示其个人的财富值,一个节点及其直接相连的子节点被定义为个小家庭。现给你一颗树,请计算出最富裕的小家庭的财富和。

MISAYAONE的博客 1238

Leetcode字符串经典九道算法题(代码及解题思路)

此文章整理于2020年校招期间,当时刷了一部分Leetcode的算法题,拿到了一些大中厂的offer。字符串9道经典算法题的解题思路及代码整理如下。

云瀚的自习室 2687

【Bug已解决】Codex CLI 报错 apply_patch 失败:无法应用补丁的解决方案

方案适用场景推荐指数统一换行符规范跨平台协作项目的标准配置⭐⭐⭐⭐⭐关闭自动格式化冲突IDE 与 Codex 并发编辑同一文件⭐⭐⭐⭐缩小任务改动范围长期有效的使用习惯优化⭐⭐⭐⭐⭐统一 UTF-8 编码涉及非 UTF-8 遗留文件的项目⭐⭐⭐提示重新读取文件单次失败后的快速恢复方式⭐⭐⭐⭐报错的本质是Codex 生成补丁时读取的文件内容,与实际应用补丁时磁盘上的文件内容出现了不一致,常见诱因包括换行符风格混用、文件被其他工具并发修改、编码问题等。

一键难忘的博客 7291

基于Simulink的单级式光伏并网系统MPPT控制仿真

本文基于Simulink平台,详细介绍了单级式光伏并网系统的MPPT控制仿真实现。主要内容包括:1)阐述MPPT作为光伏系统"智能大脑"的核心作用;2)解析单级式系统架构及扰动观察法(P&O)算法原理;3)以10kW户用系统为例,分步骤演示建模过程,包括光伏阵列搭建、P&O控制器实现(含MATLAB代码)、并网控制设计等;4)通过仿真验证系统在光照突变下的动态响应性能,MPPT效率达98.3%。文章还提出了变步长P&O等优化方向,为光伏系统仿真与控制提供实用指导。

xiaoheshang_123的博客 111

力扣刷题笔记:交替合并字符串 (LeetCode1768) — Java

简单来说,这道题就是要求我们将两个字符串穿插在一起,就像我们上学时期站队一样,原本男生一列,女生一列,可是现在要求我们男女穿插合并成一列,在这个过程中会存在有一列队伍人数比另一列多的情况,多的人自然排在后面就好了。2.就像刚刚说的那样,两个队伍合并之后会成为一个新的队伍,所以两个字符串合并之后成为一个新的字符串,所以我们需要提前创建一个结果字符串,将字符一个一个放进结果字符串。开始,通过交替添加字母来合并字符串。1.因为交替合并是需要一个一个穿插的,在这里我们想到肯定要遍历字符串中的每个字符,所以。

2501_90563889的博客 1037

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

力扣刷题篇之【字符串篇】(一)

力扣刷题数组篇

m0_62547912的博客 1273

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【leetcode 力扣刷题】字符串匹配之经典的KMP!!!

一个字符串从第一个字符开始的,不包括最后一个字符的子串;

massive_jiang的博客 4553

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

力扣刷题笔记——1768.交替合并字符串

【代码】力扣刷题笔记——1768.交替合并字符串。

m0_59127865的博客 177

力扣刷题篇——字符串

力扣刷题篇——字符串

weixin_59796310的博客 1070

LeetCode刷题-415. 字符串相加

难度:简单⭐️⭐️⭐️。

快乐的小小程序猿 153

LeetCode刷题——字符串类

文章连接:LeetCode刷题——字符串类

小杨的博客 153

leetcode刷题Day4 字符串

大奋算法一坨,学习一下,主要跟着这个仓库刷。youngyangyang04/leetcode-master: 《代码随想录》LeetCode 刷题攻略:200道经典题目刷题顺序,共60w字的详细图解,视频难点剖析,50余张思维导图,支持C++,Java,Python,Go,JavaScript等多语言版本,从此算法学习不再迷茫!🔥🔥 来看看,你会发现相见恨晚!🚀。

kelekelekle的博客 801

C++ LeetCode 力扣刷题 541. 反转字符串 II

计算字符串长度n,初始化当前段的起始索引i = 0。循环处理每一段(直到i超出字符串长度):计算当前段反转的终点(确保不越界)。用双指针反转[i, end]范围内的字符。将i增加2k,进入下一段。返回处理后的字符串。for循环适合固定步长、已知循环范围的场景(如本题),代码更简洁,意图更明确。while循环适合条件复杂、循环次数不确定的场景(如根据动态输入决定是否继续循环)。四、reversereverse函数的参数是通过起始迭代器 + 偏移量→ 反转的起点(包含)

weixin_73793168的博客 1434

Leetcode刷题笔记——数组与字符串篇

本文介绍了面试中喜欢考的与数组和字符串相关的面试题型,提供了每道题的python解法,面试加油,冲~

qq_42898642的博客 1455

我的Leetcode刷题笔记:字符串

总结了LeetCode字符串相关题型的解题思路与技巧,涵盖5类常见问题:字符串拆分替换、单词反转、字符串轮转、字符串转整数和有效数字判断。重点解析了路径加密和动态密码更新的实现方法,提供了C++代码示例和复杂度分析。对于字符串转整数(myAtoi)问题,详细说明了处理步骤,包括跳过空格、符号处理、数字转换和溢出检查。所有方案均注重边界条件处理,时间复杂度一般为O(n),空间复杂度从O(1)到O(n)不等。这些方法适用于面试准备和算法练习,强调标准化流程与高效实现。

charlie114514191的博客 1225

C++ LeetCode 力扣刷题 344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须、使用 O(1) 的额外空间解决这一问题。

weixin_73793168的博客 942

LeetCode刷题-344. 反转字符串

难度:简单⭐️⭐️⭐️。

快乐的小小程序猿 160

力扣刷题(python)50天——第五十天:反转字符串

力扣刷题(python)50天——第五十天:反转字符串 题目描述 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。 示例 1: 输入: “Let’s take LeetCode contest” 输出: “s’teL ekat edoCteeL tsetnoc” 注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。 来源:力扣(Leet...

weixin_44568780的博客 406

【Day23】力扣:LeetCode算法刷题 [927. 三等分 ] [415. 字符串相加]

字符串相加,却不可以将字符直接转化为整形来运算,而且需要输出的依旧是字符串,那么为了得到每个位置上的数字,我们可以利用ASCII码值的加减来获取。那么我们每次就将两数字之和的个位数连接进结果的字符串中,十位数则累加进下一次的两数之和中,最终也就得到了我们需要的字符串。如果遍历过程中发现遍历到的三个数字不完全相同,说明无法将二进制数组分成三个表示相同值的部分,返回{-1,-1};还需要注意的是,我们从个位数开始遍历,所以得到的字符串是从最小位数字开始的,还需要将字符串反转一下,才算完成。

ebb29bbe的博客 1218
上一篇: leetcode图论刷题总结
下一篇: leetcode栈与队列刷题总结
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值