代码随想录_字符串

embedded/2025/1/22 11:57:50/

字符串

344.反转字符串

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。

思路: 双指针

代码:

java">class Solution {public void reverseString(char[] s) {// 双指针int l = 0,r = s.length - 1;while(l < r) {char t = s[l];s[l] = s[r];s[r] = t;l++;r--;}}
}
  • 时间复杂度: O(n)
  • 空间复杂度: O(1)

541.反转字符串 II

541. 反转字符串 II

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

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

思路: 步长为2k进行循环, 每次循环内对: 2k的前k个 或 不足2k的剩余所有, 进行反转

代码:

java">class Solution {public String reverseStr(String s, int k) {char[] str = s.toCharArray();// 1. 2k 2k 循环遍历for(int i = 0;i < str.length;i += 2*k) {// 2. 找2k的前k个 或 不足2k的剩余所有 进行反转int start = i;int end = Math.min(str.length - 1,start + k - 1);while(start < end) {char t = str[start];str[start] = str[end];str[end] = t;start++;end--;}}// 3. 反转return new String(str);}
}

54.替换数字

54.替换数字(第八期模拟笔试)

image-20250116225304443

思路: 双指针, 先计算新数组的大小, 将原数组复制到新数组后, 从后往前开始替换

代码:

java">import java.util.*;
public class Main{public static void main (String[] args) {// 1. 输入Scanner sc = new Scanner(System.in);String s = sc.next();char[] oStr = s.toCharArray();// 2. 计算新数组的长度int olen = oStr.length;int nlen = olen;for(int i = 0;i < olen;i++) {if(oStr[i] >= '0' && oStr[i] <= '9') {nlen += 5;// number共6位, 覆盖原来字母一位, 每次还需再加5位}}// 3. 将原数组的内容copy到新数组char[] nStr = new char[nlen];for(int i = 0;i < olen;i++) {nStr[i] = oStr[i];}// 4. 对新数组进行处理for(int i = olen - 1,j = nlen - 1;i >= 0;i--) {if(nStr[i] >= '0' && nStr[i] <= '9') {nStr[j--] = 'r';nStr[j--] = 'e';nStr[j--] = 'b';nStr[j--] = 'm';nStr[j--] = 'u';nStr[j--] = 'n';}else {nStr[j--] = nStr[i]; }}// 5. 打印结果System.out.print(nStr);    }
}

法二: 不将原数组的内容copy到新数组

java">import java.util.*;
public class Main {public static void main (String[] args) {Scanner sc = new Scanner(System.in);String str = sc.next();char[] s = str.toCharArray();// 1. 计算新数组长度int len = s.length;int newLen = len;for(int i = 0;i < len;i++) {if(s[i] >= '0' && s[i] <= '9') {newLen+=5;}}// 2. 替换char[] c = new char[newLen];for(int i = len - 1,j = newLen - 1;i >= 0;i--) {if(s[i] >= '0' && s[i] <= '9') {c[j--] = 'r';c[j--] = 'e';c[j--] = 'b';c[j--] = 'm';c[j--] = 'u';c[j--] = 'n';}else {c[j--] = s[i];}}// 3. 输出System.out.print(c);}
}

151.反转字符串中的单词

反转字符串中的单词

image-20250117105446162

思路: 双指针, 先去掉多余空格, 再反转整个字符串, 最后反转每个单词

代码:

java">class Solution {public String reverseWords(String s) {char[] str = s.toCharArray();// 1. 去除 首尾 以及 中间 多余空格str = removeSpace(str);// 2. 将整个字符串反转reverse(str,0,str.length - 1);// 3. 将每个单词反转reverseEachWords(str);return new String(str);}// 1. 去除 首尾 以及 中间 多余空格public static char[] removeSpace(char[] str) {int slow = 0;// 1. 去空格for(int fast = 0;fast < str.length;fast++) {// 该if 每次操作一个单词if(str[fast] != ' ') {// fast所指的是字母时开始移动if(slow != 0) {// 处理是否加空格str[slow++] = ' ';}// 加单词, slow每次增加一个单词的长度while(fast < str.length && str[fast] != ' ') {// 顺序不能换, 否则下标越界str[slow++] = str[fast++];}}}// 2. 返回有效数组return Arrays.copyOfRange(str,0,slow);// 0 ~ (slow - 1}// 2. 将整个字符串反转public static void reverse(char[] str,int left,int right) {while(left < right) {str[left] ^= str[right];str[right] ^= str[left];str[left] ^= str[right];// 注意两个指针的变换不同left++;right--;}}// 3. 将每个单词反转public static void reverseEachWords(char[] str) {for(int start = 0,end = 0;end <= str.length;end++) { // end = str.length 便于与 str[end] = ' ' 统一操作if(end == str.length || str[end] == ' ') {// 走到一个单词尽头reverse(str,start,end - 1);// 反转该单词start = end + 1;// 更新start位置}}}}

55.右旋字符串(第八期模拟笔试)

右旋字符串(第八期模拟笔试)

题目描述

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

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

输入描述

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

输出描述

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

思路: 反转字符串, 先反转整体, 再依次翻转子串

代码:

java">import java.util.Scanner;
public class Main{public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = Integer.parseInt(sc.next());String s = sc.next();char[] str = s.toCharArray();int len = str.length;// 1. 整体翻转reverse(str,0,len - 1);// 2. 前半部分翻转reverse(str,0,n - 1);// 3. 后半部分翻转reverse(str,n,len - 1);System.out.print(str);}public static void reverse(char[] str,int left,int right) {while(left < right) {str[left] ^= str[right];str[right] ^= str[left];str[left] ^= str[right];left++;right--;}}
}

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

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

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

提示:

  • 1 <= haystack.length, needle.length <= 104
  • haystackneedle 仅由小写英文字符组成

思路: kmp

代码:

java">class Solution {public int strStr(String haystack, String needle) {char[] s1 = haystack.toCharArray();char[] s2 = needle.toCharArray();int m = s1.length,n = s2.length;// 1. 计算next数组int[] next = nextArray(s2,n);// 2. 匹配子串int x = 0,y = 0;// x,y分别指向s1,s2当前操作的位置while(x < m && y < n) {if(s1[x] == s2[y]) {// 两字符串当前位置相等x++;// 继续往后匹配y++;}else if(y > 0) {// 两字符串当前位置不相等, s2要匹配的不是第一个字母y = next[y];// y前退}else {// 两字符串当前位置不相等, s2要匹配的是第一个字母x++;// s1往后走}}return y == n ? x - y : -1;// s2是否完全匹配}// 1. 计算next数组public static int[] nextArray(char[] s2,int len) {// 1.1 对0 1位置的特殊判断if(len == 1) return new int[] {-1};int[] next = new int[len];next[0] = -1;next[1] = 0;// 1.2 完善next数组int cnt = 0,i = 2;while(i < len) {if(s2[i - 1] == s2[cnt]) {// 当前位置和要比对的位置相同next[i++] = ++cnt;// 前缀和累加}else if(cnt > 0) {cnt = next[cnt];// 当前位置和要比对的位置不相同, 能往前退就往前退}else {// 当前位置和要比对的位置不相同, 不能往前退, 则next[i] = 0next[i++] = 0;}}// 1.3 返回return next;}
}

注: 不能用for, 因为每次判断i不一定要往后走

459.重复的子字符串

459. 重复的子字符串

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

示例 1:

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

提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成

思路: kmp求next数组, 求到len + 1的位置, 求出整个串的最长公共前后缀, 原串减去公共前后缀剩下的就是最小重复子字符串

代码随想录讲解

代码:

java">class Solution {public boolean repeatedSubstringPattern(String s) {// 1. 计算next数组(要将整个串的最长公共前后缀计算出来)char[] cs = s.toCharArray();int len = cs.length;int[] next = getNext(cs,len);// 2. 判断原字符串的长度是否是 公共前后缀剩余串(最小子串)的整数倍if(next[len] > 0 && len % (len - next[len]) == 0) {// 要判断next[len] > 0// 3. 返回return true;}return false;}// 1. 计算next数组(要将整个串的最长公共前后缀计算出来)public int[] getNext(char[] cs,int len) {// 1. 对0 1位置的特殊判断if(len == 1) {return new int[] {-1,0};}// 2. 补充next数组int i = 2,cnt = 0;// i代表当前处理的位置(后缀),cnt前缀的位置int[] next = new int[len + 1];// 要计算整个数组的最长公共前后缀next[0] = -1;next[1] = 0;while(i <= len) {if(cs[i - 1] == cs[cnt]) {next[i++] = ++cnt;}else if (cnt > 0) {cnt = next[cnt];}else {next[i++] = cnt;}}// 3. 返回return next;}
}

http://www.ppmy.cn/embedded/156043.html

相关文章

分布式系统通信解决方案:Netty 与 Protobuf 高效应用

分布式系统通信解决方案&#xff1a;Netty 与 Protobuf 高效应用 一、引言 在现代网络编程中&#xff0c;数据的编解码是系统设计的一个核心问题&#xff0c;特别是在高并发和低延迟的应用场景中&#xff0c;如何高效地序列化和传输数据对于系统的性能至关重要。随着分布式系…

玉米植物结构受乙烯生物合成基因 ZmACS7 的调控

摘要&#xff1a; 植物高度和叶片角度是玉米&#xff08;Zea mays&#xff09;植物结构的两个关键决定因素&#xff0c;与高种植密度下的抗倒伏性和冠层光合作用密切相关。这两个性状主要由几种植物激素调节。然而&#xff0c;乙烯在调节玉米植物结构中的机制&#xff0c;特别…

excel实用工具

持续更新… 文章目录 1. 快捷键1.1 求和 2. 命令2.1 查找 vloopup 1. 快捷键 1.1 求和 windows: alt mac : command shift T 2. 命令 2.1 查找 vloopup vlookup 四个入参数 要查找的内容 &#xff08;A2 6xx1&#xff09;查找的备选集 &#xff08;C2:C19&#xff09;…

【K8S系列】在 K8S 中使用 Values 文件定制不同环境下的应用配置

写在前面 因为有小伙伴问这个问题&#xff0c;因此用这篇文章详细讲解一下&#xff1a;在k8s中怎么实现通过使用Values文件&#xff0c;定制不同环境&#xff08;开发、测试、预发、生产&#xff09;下的应用配置的问题。 希望对你有所帮助~ 一、基础介绍 &#xff08;一&…

VSCode+EIDE 环境搭建

一、安装插件 请在魔法的情况下&#xff0c;去下载安装该插件。 二、配置 导入一个例程。 编译器选择 AC5或者AC6&#xff0c;当然AC5需要你自己去整&#xff0c;具体可以参照这篇文章Keil5 MDK安装Compiler Version5&#xff08;即ARM Compiler 5&#xff0c;简称AC5&#x…

【科研建模】Pycaret自动机器学习框架使用流程及多分类项目实战案例详解

Pycaret自动机器学习框架使用流程及项目实战案例详解 1 Pycaret介绍2 安装及版本需求3 Pycaret自动机器学习框架使用流程3.1 Setup3.2 Compare Models3.3 Analyze Model3.4 Prediction3.5 Save Model4 多分类项目实战案例详解4.1 ✅ Setup4.2 ✅ Compare Models4.3 ✅ Experime…

如何用数据编织、数据虚拟化与SQL-on-Hadoop打造实时、可扩展兼容的数据仓库?

在大数据技术迅猛发展的背景下&#xff0c;许多人认为传统数据仓库已过时。然而&#xff0c;这种观点忽略了数据仓库的核心价值&#xff1a;统一的数据视图、强大的业务逻辑支撑以及丰富的数据分析能力。在企业数据架构转型中&#xff0c;数据仓库不仅未被淘汰&#xff0c;反而…

蓝桥杯小白备考指南

一、了解蓝桥杯 蓝桥杯大赛是工业和信息化部人才交流中心举办的全国性专业信息技术赛事 &#xff0c;旨在促进软件和信息领域专业技术人才培养&#xff0c;提升高校毕业生的就业竞争力。比赛涵盖多个编程语言组别&#xff0c;如 Java、C/C、Python 等。不同组别和参赛类别&…