算法题总结(八)——字符串

news2024/10/5 23:54:29

531、反转字符串二

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例 1:

输入:s = "abcdefg", k = 2
输出:"bacdfeg"

示例 2:

输入:s = "abcd", k = 2
输出:"bacd"

要规律的处理字符串的时候,在for循环上,每次有规律的递增,从开始+k,判断与总长度的大小

class Solution {
    public String reverseStr(String s, int k) {
        char[] ch=s.toCharArray();
        for(int i=0;i<ch.length;i+=2*k)   //控制每次循环的开头
        {
            //只要剩余的字符大于等于k个,就翻转从i开始的k个字符。包括两种情况:剩余长度大于等于2k、在k和2k中间。
            if(i+k-1<ch.length)   //从i开始的k个字符,序号是i+k-1 
            {
                reverse(ch,i,i+k-1);
            }
                //剩余字符少于 k 个,则将剩余字符全部反转
            else
            {
                reverse(ch,i,ch.length-1);
            }
        }
        return new String(ch);

    }
    //定义一个反转函数
    public void reverse(char[] ch,int i,int j)
    {
        while(i<j)
        {
            char t=ch[i];
            ch[i]=ch[j];
            ch[j]=t;
            i++;
            j--;
        }
    }
}

ACM模式-替换数字

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。

例如,对于输入字符串 “a1b2c3”,函数应该将其转换为 “anumberbnumbercnumber”。

对于输入字符串 “a5b”,函数应该将其转换为 “anumberb”

输入:一个字符串 s,s 仅包含小写字母和数字字符。

输出:打印一个新的字符串,其中每个数字字符都被替换为了number

样例输入:a1b2c3

样例输出:anumberbnumbercnumber

数据范围:1 <= s.length < 10000。

使用一个StringBuilder

import  java.util.*;	

class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s = in.nextLine();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (Character.isDigit(s.charAt(i))) {
                sb.append("number");
            }else sb.append(s.charAt(i));
        }
        System.out.println(sb);
    }
}

151、反转字符串中的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 1:

输入:s = "the sky is blue"
输出:"blue is sky the"

示例 2:

输入:s = "  hello world  "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。

示例 3:

输入:s = "a good   example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

思路:整体反转+局部反转

class Solution {
    /**
     * 不使用Java内置方法实现
     * <p>
     * 1.去除首尾以及中间多余空格
     * 2.反转整个字符串
     * 3.反转各个单词
     */
    public String reverseWords(String s) {
        // System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
        // 1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        // 2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }

    private StringBuilder removeSpace(String s) {
        // System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
        int start = 0;
        int end = s.length() - 1;
        while (s.charAt(start) == ' ') start++;
        while (s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        //去除中间的空格
        while (start <= end) {
            char c = s.charAt(start);
            //如果不是空格,或者是第一个空格,就加入sb中
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            start++;
        }
        return sb;
    }

    /**
     * 反转字符串指定区间[start, end]的字符
     */
    public void reverseString(StringBuilder sb, int start, int end) {
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
    }

    private void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 0;
        int n = sb.length();
        //使用双指针,对每个单词进行翻转
        while (end < n) {
            while (sb.charAt(end) != ' ') {
                end++;
            }
            reverseString(sb, start, end - 1);
            start = end + 1;
            end = start;
        }
    }
}

这道题的关键点就是1、使用sb去除中间的字符串,2、先整体翻转,再使用双指针逐个单词进行翻转。

ACM模式-右旋字符串

字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。

例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。

输入:输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。

输出:输出共一行,为进行了右旋转操作后的字符串。

样例输入:

2
abcdefg

样例输出:

fgabcde

数据范围:1 <= k < 10000, 1 <= s.length < 10000;

import java.util.Scanner;  //导入包

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        String s = in.nextLine();

        int len = s.length();  //获取字符串长度
        char[] chars = s.toCharArray();
        reverseString(chars, 0, len - 1);  //反转整个字符串
        reverseString(chars, 0, n - 1);  //反转前一段字符串,此时的字符串首尾尾是0,n - 1
        reverseString(chars, n, len - 1);  //反转后一段字符串,此时的字符串首尾尾是n,len - 1

        System.out.println(chars);

    }

    public static void reverseString(char[] ch, int start, int end) {
        while (start < end) {
            char t=ch[start];
            ch[start]=ch[end];
            ch[end]=t;
            start++;
            end--;
        }
    }
}

28、找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

即KMP算法:

KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。

前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。

那么什么是前缀表:记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀

class Solution {
    //给字符串s构造next数组
    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];
            }
            //相等的话;j++
            if(s.charAt(i)==s.charAt(j))
                j++;
            next[i]=j;
        }
    }

    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++)
        {
            //不相等的时候,用next数组回溯
            while(j>0 && haystack.charAt(i)!=needle.charAt(j))
            j=next[j-1];
            if(haystack.charAt(i)==needle.charAt(j))
                j++;
            if(j==needle.length())
                return i+1-j;
        }
        return -1;

    }
}

459、重复的子字符串

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false

示例 3:

输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

移动匹配

当一个字符串s:abcabc,内部由重复的子串组成,那么这个字符串的结构一定是这样的:

也就是由前后相同的子串组成。

那么既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前面的子串做后串,就一定还能组成一个s,如图:

所以判断字符串s是否由重复子串组成,只要两个s拼接在一起,里面还出现一个s的话,就说明是由重复子串组成。

当然,我们在判断 s + s 拼接的字符串里是否出现一个s的的时候,要刨除 s + s 的首字符和尾字符,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s。

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        //由于是重复构成的,所以两个拼接,中间一定能找到子串s
        int n=s.length();
        String str=s+s;
        String substr =str.substring(1,2*n-1); //去头去尾
        int index=substr.indexOf(s); 
        if(index != -1) 
            return true;
        else 
            return false;

    }
}

字符串常用方法:

双指针法、多次反转,转化为sb

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

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

相关文章

VTK有向包围盒

文章目录 一、vtkOBBTree1.1 几种树结构的对比1.2 获取线段与数据集的交点1.3 OBB树可视化1.4 对齐两个数据集1.5 圆柱形有向包围盒 本文的主要内容&#xff1a;简单介绍VTK中有向包围盒的相关功能。 主要涉及vtkOBBTree类。 哪些人适合阅读本文&#xff1a;有一定VTK基础的人。…

python全栈开发是什么?

全栈指掌握多种技能&#xff0c;并能利用多种技能独立完成产品。通俗的说就是与这项技能有关的都会&#xff0c;都能独立完成。 python&#xff0c;因为目前很火&#xff0c;能开发的项目很多。例如&#xff1a;web前端后端&#xff0c;自动化运维&#xff0c;软件、小型游戏开…

基于ssm的二手手机商城的设计与实现

文未可获取一份本项目的java源码和数据库参考。 题目简介&#xff1a; 随着时代的发展与科技的进步&#xff0c;人们的物质生活水平越来愈高&#xff0c;对智能化电子产品的需求也越来越高&#xff0c;手机就是一个很好的表现。近年来&#xff0c;随着华为、小米、vivo、ipho…

问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题

​ 编码: 把字符转换成字节序列的过程。因为计算机只能处 理二进制数据&#xff0c;所以不能直接处理文本&#xff0c;需要先把文本转换为二进制数据。 解码: 把二进制数据转换成字符的过程。把接收到的数据转换成程序中使用的编码方式。 ​ 这个报错原因就是编码和解码没达成…

地理定位营销与开源AI智能名片O2O商城小程序的融合与发展

摘要&#xff1a;本文阐述地理定位营销的概念、手段及其在商业中的应用&#xff0c;探讨开源AI智能名片O2O商城小程序如何与地理定位营销相结合&#xff0c;为企业营销带来新的机遇与挑战。 一、引言 在当今数字化营销的时代&#xff0c;地理定位营销已成为一种重要的营销手段…

【C语言】分支与循环

文章目录 前言if语句关系操作符逻辑操作符&#xff1a;&& , || , &#xff01;switch语句if语句和switch语句的对比 while循环for循环do-while循环break和continue语句循环嵌套goto语句 前言 C语⾔是结构化的程序设计语⾔&#xff0c;这⾥的结构指的是顺序结构、选择&…

【GeekBand】C++设计模式笔记5_Observer_观察者模式

1. “组件协作”模式 现代软件专业分工之后的第一个结果是“框架与应用程序的划分”&#xff0c;“组件协作”模式通过晚期绑定&#xff0c;来实现框架与应用程序之间的松耦合&#xff0c;是二者之间协作时常用的模式。典型模式 Template MethodStrategyObserver / Event 2.…

D28【python 接口自动化学习】- python基础之输入输出与文件操作

day28 输入 学习日期&#xff1a;20241005 学习目标&#xff1a;输入输出与文件操作&#xfe63;-40 输入&#xff1a;如何接收用户通过键盘输入的数据&#xff1f; 学习笔记&#xff1a; 输入设备与输入方式 Input函数 命令行参数 可选参数 必填参数 强制转换参数类型 总…

认知战认知作战:2024年10月4日美国非农数据发布背景下的全球认知战分析——策略、手段与应对

认知战认知作战&#xff1a;2024年10月4日美国非农数据发布背景下的全球认知战分析——策略、手段与应对 关键词&#xff1a;认知战,非农数据,美联储,加息,信息操控,心理战,市场恐慌,虚假信息,防御方,攻击方,舆论引导,虚假数据,断章取义,金融市场,信息不对称,经济政策,虚假专家…

基金好书入门阅读笔记《基金作战笔记:从投基新手到配置高手的进阶之路》1

今年的新书《基金作战笔记&#xff1a;从投基新手到配置高手的进阶之路》&#xff0c;趁着国庆前这个风潮&#xff0c;拿来学习下。 第一章 军规 军规1&#xff1a;莫求暴富&#xff0c;为自己设定一个长期目标。 军规2&#xff1a;永不满仓&#xff0c;找到自己的资产配置中…

基于Python的自然语言处理系列(24):BiDAF(双向注意力流)

在自然语言处理领域,机器阅读理解(Machine Comprehension, MC)是一个重要的任务。在这篇博文中,我们将实现论文 BiDAF 中提出的双向注意力流模型。BiDAF 主要改进了传统注意力机制中的早期信息摘要问题,并引入了字符嵌入来加强对单词细粒度信息的理解。 1. 加载 SQuAD 数据…

在VSCode中编写Html

1.下载VSCode&#xff1a;Download Visual Studio Code - Mac, Linux, Windows 2.安装插件&#xff1a; 简体中文插件可把界面改成中文 3.打开一个文件夹&#xff1a;用于在这个文件夹内写Html 5.新建文件&#xff1a;sheet.html,按 &#xff01; tab键可以生成HTML文件标准格式…

网络基础 【HTTP】

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux初窥门径⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a; &#x1f4bb;操作环境&#xff1a; CentOS 7.6 华为云远程服务器 &#x1f339;关注我&#x1faf5;带你学习更多Linux知识…

JC4805快速入门

目录 一、产品概述二、驱动器参数2.1、产品尺寸2.2、技术参数 三、接口说明3.1、电源接口3.2、电机接口3.3、USB接口3.4、CAN接口3.5、SPI接口3.6、ABZ接口3.7、Hall接口3.8、电机温度检测3.9、状态指示灯 四、硬件接线五、软件操作5.1、设置参数5.2、零点校准5.3、运行调试5.4…

【JavaWeb】javaweb目录结构简介【转】

以上图说明&#xff1a; bbs目录代表一个web应用bbs目录下的html,jsp文件可以直接被浏览器访问WEB-INF目录下的资源是不能直接被浏览器访问的web.xml文件是web程序的主要配置文件所有的classes文件都放在classes目录下jar文件放在lib目录下

Gitee创建仓库,提交代码到自己的fork,合并到主分支

一、创建仓库 1、创建仓库 2、添加仓库成员 3、初始化项目 3.1 在项目目录中右击用Git Bash here打开&#xff0c;先git init创建新的空白存储库&#xff0c;使现有项目成为Git项目。 3.2 克隆仓库地址&#xff0c;拉取新建的仓库&#xff0c;此时项目文件夹中会出现一个仓库…

CNN-GRU时序预测 | MATLAB实现CNN-GRU卷积门控循环单元时间序列预测

时序预测 | MATLAB实CNN-GRU卷积门控循环单元时间序列预测 目录 时序预测 | MATLAB实CNN-GRU卷积门控循环单元时间序列预测预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 本次运行测试环境MATLAB2020b 提出了一种基于卷积神经网络(Convolutional Neural Network…

《 C++ 修炼全景指南:十四 》大数据杀手锏:揭秘 C++ 中 BitSet 与 BloomFilter 的神奇性能!

本篇博客深入探讨了 C 中的两种重要数据结构——BitSet 和 BloomFilter。我们首先介绍了它们的基本概念和使用场景&#xff0c;然后详细分析了它们的实现方法&#xff0c;包括高效接口设计和性能优化策略。接着&#xff0c;我们通过对比这两种数据结构的性能&#xff0c;探讨了…

Ray_Tracing_The_Next_Week下

5image Texture Mapping 图像纹理映射 我们之前虽然在交点信息新增了uv属性&#xff0c;但其实并没有使用&#xff0c;而是通过p交点笛卡尔坐标确定瓷砖纹理或者大理石噪声纹理的值 现在通过uv坐标读取图片&#xff0c;通过std_image库stbi_load&#xff08;path&#xff09;…

“米哈游悄然布局未来科技:入股星海图,共绘具身智能机器人新篇章“

米哈游悄然入股具身智能机器人公司:技术布局与未来展望 近日,米哈游阿尔戈科技有限公司宣布入股具身智能机器人公司星海图,这一消息在行业内引起了广泛关注。米哈游,这家以游戏开发而闻名的企业,近年来正逐步扩大其在人工智能和新兴科技领域的投资布局,此次入股星海图正是…