首页 > 其他分享 >给自己复盘的随想录笔记-字符串练习题

给自己复盘的随想录笔记-字符串练习题

时间:2024-09-04 15:54:43浏览次数:11  
标签:练习题 String int res 随想录 public str 字符串 复盘

反转字符串

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

双指针+元素交换 

class Solution {
    public void reverseString(char[] s) {
    char temp;
    int l=0,r=s.length-1;
    while(l<r){
        temp=s[l];
        s[l]=s[r];
        s[r]=temp;
        l++;
        r--;
    }
    }
}

反转字符串ii

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

这个题目就是上一个题目的加强版本,我的解法不具有通用性,脑子太死了

找到反转区间的规律,然后对其进行反转;

反转区间的确定+区间反转

class Solution {
    public String reverseStr(String s, int k) {
        char[] cs = s.toCharArray();
        int n = s.length();
        for (int l = 0; l < n; l = l + 2 * k) {
            int r = l + k - 1;
            reverse(cs, l, Math.min(r, n - 1));
        }
        return String.valueOf(cs);
    }
    void reverse(char[] cs, int l, int r) {
        while (l < r) {
            char c = cs[l];
            cs[l] = cs[r];
            cs[r] = c;
            l++; r--;
        }
    }
}

替换数字

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

统计数组个数,新建数组进行扩容,给数组进行赋值; 

import java.util.*;

public class Main{
    
    public static void main(String[] args){
     Scanner sc=new Scanner(System.in);  
     String s= sc.next();
     
     int len=s.length();
     int count=0;
     for(int i=0;i<len;i++){
         if(s.charAt(i)>='0'&&s.charAt(i)<='9'){
             count++;
         }
     }
     
     char[] res=new char[len+count*5];
     for(int j=len-1,k=len+count*5-1;j>=0;j--){
         if(s.charAt(j)>='0'&&s.charAt(j)<='9'){
             res[k--]='r';
             res[k--]='e';
             res[k--]='b';
             res[k--]='m';
             res[k--]='u';
             res[k--]='n';
             
         }else{
             res[k--]=s.charAt(j);
         }
     }
     System.out.println(new String(res));
        
        
        
    }
      
}

翻转字符串中的单词

双指针找到单词的所在区间,然后存入结果

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

class Solution {
    public String reverseWords(String s) {
    s.trim();
    int l=s.length()-1,r=s.length()-1;
    StringBuilder res=new StringBuilder();
    while(l>=0){
        while(l>=0&&s.charAt(l)!=' ') l--;
        res.append(s.substring(l+1,r+1)+' ');
        while(l>=0&&s.charAt(l)==' ') l--;
        r=l;
    }
    return res.toString().trim();
    }
}

1.
s是String类型
s.trim() 方法用于移除字符串两端的空白字符,包括空格、制表符、换行符等。这行代码的作用是将变量 s 中存储的字符串两端的空白字符去掉,并将处理后的字符串重新赋值给变量 s。

2.
为什么定义res是StringBuilder类型
在Java中,String 类型是不可变的(immutable),这意味着每次对字符串进行修改时,都会创建一个新的字符串对象。如果在一个循环中不断地对字符串进行修改,比如拼接操作,那么每次修改都会生成一个新的字符串对象,这会导致大量的内存分配和垃圾回收,从而降低程序的性能。

而 StringBuilder 类是可变的(mutable),它提供了一个可变的字符序列,可以在不生成大量临时对象的情况下进行字符串拼接操作。这使得 StringBuilder 成为处理字符串拼接的首选方式,尤其是在循环中进行大量拼接操作时。


3.
res是StringBuilder类型
res.append(...):这是调用 res 字符串的 append 方法,将拼接后的字符串添加到 res 的末尾。

4.
String substring(int beginIndex, int endIndex)
beginIndex:子字符串开始处的索引(包括此索引处的字符)。
endIndex:子字符串结束处的索引(不包括此索引处的字符)。
返回从 beginIndex 到 endIndex - 1 的子字符串。
相当于左闭右开

分裂+倒序

class Solution {
    public String reverseWords(String s) {
   String[] strs=s.trim().split(" ");
   StringBuilder res=new StringBuilder();

   for(int i=strs.length-1;i>=0;i--){
    if(strs[i].equals("")) continue;
    res.append(strs[i]+" ");
   }
   return res.toString().trim();
    }
}

1.
   String[] strs=s.trim().split(" ");
     split 方法是 Java 中 String 类的一个非常有用的实例方法,它用于将字符串分割成子字符串数组。这个方法根据指定的正则表达式来分割原始字符串。
     split 方法需要一个正则表达式作为参数,而正则表达式应该用双引号包围,即 " " 而不是 ' '
     " ":匹配空格字符。
",":匹配逗号字符。
[,;]:匹配逗号或分号字符。
     
2.
  if(strs[i].equals("")) continue;
在 Java 中,不能直接将 char 类型与 String 类型进行比较。如果需要比较字符串中的字符,应该将 char 转换为 String,或者直接比较 String 类型的变量。所以是“”双引号,表示空单词

另外,使用 equals 方法比较字符串
     
3.
方法一和方法二注意细节,方法一是引入字符数组的形式处理,方法二引入字符串数组的形式处理
 

右旋字符串

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

import java.util.Scanner;

public class Main{
    
    public static void main(String[] args){
       Scanner in = new Scanner(System.in);
        int k = Integer.parseInt(in.nextLine());
        String s = in.nextLine();
        
        char[] str=s.toCharArray();
        int len=str.length;
        rever(str,0,len-1);
        rever(str,0,k-1);
        rever(str,k,len-1);
        System.out.println(new String(str));
    }
    public static void rever(char[] str,int start,int end){
        char temp;
        while(start<end){
            temp=str[start];
            str[start]=str[end];
            str[end]=temp;
            start++;
            end--;
        }
    }
}

     Scanner in = new Scanner(System.in);
        int k = Integer.parseInt(in.nextLine());
        String s = in.nextLine();
        

 换行读取键入的对象

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

巧思妙想,我自己没有想到

class Solution {
    public int strStr(String ss, String pp) {
        int lenss=ss.length(),lenpp=pp.length();
        char[] s=ss.toCharArray(),p=pp.toCharArray();

        for(int i=0;i<=lenss-lenpp;i++){
            int a=i,b=0;
            while(b<lenpp&&s[a]==p[b]){
                a++;
                b++;
            }
            if(b==lenpp) return i;
        }
        return -1;
    }
}

这道题可以用KMP算法,我先留个尾巴,回头再来看

28. 找出字符串中第一个匹配项的下标 - 力扣(LeetCode)

重复的子字符串

我发现简单题其实不简单,因为考察的更多是思路;

反而难度的题目其实就是麻烦

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

 这个代码给的太优雅了,我真的佩服

class Solution {
   public boolean repeatedSubstringPattern(String s) {
        String str = s + s;
        return str.substring(1, str.length() - 1).contains(s);
}
}

思路分析:假设字符串s是由s1+s2组成的,s+s后,str就变成了s1+s2+s1+s2;

去掉首尾,破环了首尾的s1和s2,变成了s3+s2+s1+s4;

此时str中间就是s2+s1,如果s是循环字串,也就是s1=s2,所以str中间的s2+s1就和原字符串相等。如果s不是循环字串,s1!=s2,那么s1+s2是不等于s2+s1的,也就是str中间不包含s

主要是要把重复子串全部理解为重复两次,不要考虑太多

另一个思路

也特别奇思妙想

但是我打死都想不出来

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

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int lens = s.length(), i = 0;
        while (++i < lens) {
            if (lens % i != 0) continue;
            if (s.substring(lens - i, lens).equals(s.substring(0, i))) // 判断x是不是基串
                if (s.substring(i, lens).equals(s.substring(0, lens - i))) return true; // 判断拿去x后是否相等
        }
        return false;
    }
}

标签:练习题,String,int,res,随想录,public,str,字符串,复盘
From: https://blog.csdn.net/weixin_46321761/article/details/141888716

相关文章

  • 代码随想录day50 || 图论基础
    图论基础定义图的构造方式1,邻接矩阵矩阵位置array[i][j]=k,i表示节点i,j表示节点j,[i][j]表示i-->j存在一条边,k表示的是边的权重邻接矩阵的优点:表达方式简单,易于理解检查任意两个顶点间是否存在边的操作非常快适合稠密图,在边数接近顶点数平方的图中,邻接矩阵是一种空......
  • 代码随想录 刷题记录-26 图论 (3)最小生成树
    一、prim算法精讲53.寻宝解题思路最小生成树是所有节点的最小连通子图,即:以最小的成本(边的权值)将图中所有节点链接到一起。图中有n个节点,那么一定可以用n-1条边将所有节点连接到一起。那么如何选择这n-1条边就是最小生成树算法的任务所在。例如本题示例中的无......
  • 代码随想录算法day7 - 字符串1
    题目1344.反转字符串编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解决这一问题。示例1:输入:s=["h","e","l","l","o"]输出:["o","l","l","e",&qu......
  • 千字复盘:程序员做AI副业、个人IP的进
    大家好,我是程序员X小鹿,前互联网大厂程序员,自由职业2年+,也一名AIGC爱好者,持续分享更多前沿的「AI工具」和「AI副业玩法」,欢迎一起交流~最近一直在外面玩,所以更新地不是很勤。上周末去北京参加了AI破局合伙人线下大会,写了一下复盘。有些问题,可能一些在做个人IP、做副业的同学也正......
  • 代码随想录算法训练营|Day06 LeetCode 242.有效的字母异位词,349.两个数组的交集,202.快
    理论知识哈希表是根据关键码的值而直接进行访问的数据结构,一般用来快速判断一个元素是否出现在集合里映射——哈希函数哈希碰撞线性探测法拉链法常用的哈希结构数组set(集合)map(映射)242.有效的字母异位词242.有效的字母异位词-力扣(LeetCode)classSolution{......
  • 算法练习题10:leetcode76最小覆盖子串-滑动窗口
    目录题目题目描述约束条件解决思路代码getOrDefault(c,0) 方法方法签名参数返回值示例getOrDefault 与 get 的主要区别Integer 题目题目描述给定两个字符串s和t,请你在字符串s中找到包含t中所有字符的最小子串。要求:        如果 s ......
  • 代码随想录day16--图论
    题目描述:给定一个由1(陆地)和0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。输入描述:第一行包含两个整数N,M,表示矩阵的行数和列数。后续N行,每行包含M个数字,数字为1或者0。输出描......
  • 代码随想录算法训练营,9月3日 | 454.四数相加II,383. 赎金信,15. 三数之和,18. 四数之和
    454.四数相加II题目链接:454.四数相加II文档讲解︰代码随想录(programmercarl.com)视频讲解︰四数相加II日期:2024-09-03想法:4个数组,两两分开遍历时间复杂度低点,用一个map,key是i+j的值,value是出现次数,对nums3、4只需要判断0-k-l在不在map里,最后依次加上出现次数就行了。Java代......
  • 代码随想录算法训练营第32天|509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯
    目录509.斐波那契数1、题目描述2、思路3、code4、复杂度分析70.爬楼梯1、题目描述2、思路3、code746.使用最小花费爬楼梯1、题目描述2、思路3、code4、复杂度分析509.斐波那契数题目链接:link1、题目描述斐波那契数(通常用F(n)表示)形成的序列称为斐波那......
  • 代码随想录训练营完结总结
    在参加代码随想录的很久之前,我就听闻了卡哥的大名,也在B站上看到了相关的视频,但由于自制力一直不行,所有总是坚持不下去,当时好像就只看到了数组,甚至于链表都没开始看,就已经放弃了。想着这个暑假不能荒废了,就狠下心报名了训练营。并在这个暑假完成了代码随想录的一刷,自我感觉对于算法......