当前位置: 首页 > article >正文

Day8补代码随想录 字符串part1 344.反转字符串|541.反转字符串II|卡码网:54.替换数字

论文差不多搞定了,开始补落下的这几天的算法题

344.反转字符串

链接

https://programmercarl.com/0344.%E5%8F%8D%E8%BD%AC%E5%AD%97%E7%AC%A6%E4%B8%B2.html

题目

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

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

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:
输入:[“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]

示例 2:
输入:[“H”,“a”,“n”,“n”,“a”,“h”]
输出:[“h”,“a”,“n”,“n”,“a”,“H”]

思路

  • 解读
    • 难点,原地修改输入数组,O(1)的额外空间
    • 考察字符串reverse函数的实现,要明确什么时候用库函数,什么时候不用库函数
  • Karl思路
    • 首尾交换→向中间移动→两个指针
    • code1
      class Solution {
          public void reverseString(char[] s) {
              int length=s.length;
              for (int i=0,j=length-1;i<length/2;i++,j--){
                  char temp=s[i];
                  s[i]=s[j];
                  s[j]=temp;
      
              }  
          }
      }
      
  • Carl给的答案是:用while 循环
    class Solution {
        public void reverseString(char[] s) {
            int length=s.length;
            int l=0;
            int r=length-1;
            while(l<r){
                char temp=s[l];
                s[l]=s[r];
                s[r]=temp;
                l++;
                r--;
    
    
            }
    
        }
    }
    
  • 两个循环体
    • for(初始化;条件;更新){/循环体}
    • while(条件){//循环体 更新;}

总结

  • 字符串和数组的区别?
  • 库函数reverse();普通函数:swap();(C++)语言,
  • 在JAVA中用临时变量手动实现交换逻辑。
  • 低级错误
    • 变量必须声明;
    • 返回类型是void的,并且是原地变换数组,不用设置返回值
    • 在for中如果声明for (int i=0,int j=length-1;i<length/2;i++,j–)是不对的,在for循环的初始化部分,如果要声明多个变量,不能重复写数据类型,只能声明一次数据类型。

541.反转字符串II

题目

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

如果剩余字符少于 k 个,则将剩余字符全部反转。

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

示例:

输入: s = “abcdefg”, k = 2
输出: “bacdfeg”

思路

  • 我的思路
    • 两层循环,一层循环全部,里层每循环2k个就翻转一次,然后2k再加一次2k。
    • 剩余的值再进行一次for循环,确定范围。但是我的方法非常繁杂,确定循环的始末很容易错
    • class Solution {
          public String reverseStr(String s, int k) {
              size=s.length ();
              //最后一个不满足2k的序列怎么处理
              int leaf=size%(2*k);
              int leafstart=size-leaf;
      
              for(int i=0;i<leafstart;i++){
                  int l=0;
                  int r=2k-1;
                  if(i=2k-1){   
                      while(l<r){
                          String temp=s[l];
                          s[l]=s[r];
                          s[r]=temp;
                          l++;
                          r--;
                          //abcdefghijk  k-2, 3,6
                          l=l+2k;
                          r=r+2k;
                      }  
                  }
                  else{continue;}
              }
              while(leafstart!=size-1){
              for(int i=leafstart,j=size-1;i<size-1;i++,j--){
                  String temp_leaf=s[leafstart];
                  s[leaftstart]=s[j];
                  s[j]=temp_leaf;
              }
      
          }
          }
      }
      
  • gpt修改后
    class Solution {
        public String reverseStr(String s, int k) {
            // 将字符串转换为字符数组
            char[] chars = s.toCharArray();
            int size = chars.length;
            int leaf = size % (2 * k); // 计算不满2k的剩余部分
            int leafstart = size - leaf; // 剩余部分的起始位置
    
            int l = 0;
            int r = 2 * k - 1;
    
            // 遍历每个2k块,反转前k个字符
            for (int i = 0; i < leafstart; i++) {
                if (i % (2 * k) == 0) { // 每2k块进行一次反转,找起点,而不是找2k块的终点
                    l = i;
                    r = Math.min(i + k - 1, size - 1); // 确保右边界不越界
    
                    // 反转[l, r]区间的字符
                    while (l < r) {
                        char temp = chars[l];
                        chars[l] = chars[r];
                        chars[r] = temp;
                        l++;
                        r--;
                    }
                }
            }
    
            // 处理剩余字符
            if (leaf > 0) {
                l = leafstart;
                r = Math.min(leafstart + k - 1, size - 1); // 确保右边界不越界
    
                while (l < r) {
                    char temp = chars[l];
                    chars[l] = chars[r];
                    chars[r] = temp;
                    l++;
                    r--;
                }
            }
    
            // 将字符数组转换回字符串并返回
            return new String(chars);
        }
    }
    
    
  • Karl
    • 更新:我的代码的问题:选择i++遍历有冗余(需要加if (i % (2 * k) == 0)) 解决办法:i+=2k就可以了
    • 翻转始末[i,i+k)区间,i+k不能超过边界条件,对边界的处理问题
    • class Solution {
          public String reverseStr(String s, int k) {
              char[] ch=s.toCharArray();
              for(int i=0;i<ch.length;i+=2*k){
                  //始末条件限制,还需要不满足2k的时候,很巧妙,用了个min函数
                  int start=i;
                  int end=Math.min(ch.length-1,i+k-1);//左闭右开
                  while(start<end){
                      char temp=ch[start];
                      ch[start]=ch[end];
                      ch[end]=temp;
                      start++;
                      end--;
                  }
              }
              return new String(ch);
          }
      }
      
      

总结

  • String要转换成数组,char[] ch=s.toCharArray();
  • 获取长度 .length获取数组的长度;.length()是一个方法,获取字符串的长度。
  • 【很关键】解决不满足2k的剩余数组的时候,用了个很巧妙的方法,int end=Math.min(ch.length-1,i+k-1);//左闭右开,确定了即使不足2k,可以翻转剩余的数组。
  • 【很关键】i+=2k循环思路
  • 低级错误
    • end++顺手写成end–;
    • i<ch.length写成了-1

卡码网:54.替换数字

题目

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

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

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

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

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

样例输入:a1b2c3

样例输出:anumberbnumbercnumber

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

【对于线性数据结构的填充或删除,后序处理会高效的多】

思路

  • 我的思路
    • 识别数字后,替换为number
    • 问题,
      • 如果替换的话,数组长度就变了,后续的字母的位置都要变,怎么处理
      • 替换是直接用==吗?怎么识别数数字?
  • Carl
    • 预先扩充在数组尾部填充number的大小
    • 从后向前重新放入字母和数字,当遇到数字时,从后向前放入number
    • 双指针,i指向新长度的末尾,j指向旧长度的末尾
    • ×从前向后填充O(n^2) ;从后向前填充的好处:1.不用申请新数组 2.从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要讲添加元素之后的所有元素向后移动的问题。
  • CODE
    • import java.util.Scanner;
      
      public class Main {
        
          public static String replaceNumber(String s) {
              int count = 0; // 统计数字的个数
              int sOldSize = s.length();
              for (int i = 0; i < s.length(); i++) {
                  if(Character.isDigit(s.charAt(i))){
                      count++;
                  }
              }
              // 扩充字符串s的大小,也就是每个空格替换成"number"之后的大小
              char[] newS = new char[s.length() + count * 5];
              int sNewSize = newS.length;
              // 将旧字符串的内容填入新数组
              System.arraycopy(s.toCharArray(), 0, newS, 0, sOldSize);
              // 从后先前将空格替换为"number"
              for (int i = sNewSize - 1, j = sOldSize - 1; j < i; j--, i--) {
                  if (!Character.isDigit(newS[j])) {
                      newS[i] = newS[j];
                  } else {
                      newS[i] = 'r';
                      newS[i - 1] = 'e';
                      newS[i - 2] = 'b';
                      newS[i - 3] = 'm';
                      newS[i - 4] = 'u';
                      newS[i - 5] = 'n';
                      i -= 5;
                  }
              }
              return new String(newS);
          };
          public static void main(String[] args) {
              Scanner scanner = new Scanner(System.in);
              String s = scanner.next();
              System.out.println(replaceNumber(s));
              scanner.close();
          }
      }
      

总结

  • s.charAt(i) 去字符串String在i处的字符Char。(Char)在某处(at)
  • Character.isDigit(a) 判断(Character类)是否(is)为数字(Digit)
  • char[] newArray = new char[length]; char[] newS = new char[s.length() + count * 5];

这道题对我来说难度太大,有一些语法记不住,二刷再学一遍


http://www.kler.cn/a/455512.html

相关文章:

  • 进军AI大模型-环境配置
  • pyQT + OpenCV相关练习
  • 【WRF模拟】如何得到更佳的WRF模拟效果?
  • 通过交叉实现数据触底分页效果new IntersectionObserver()(html、react、vue2、vue3)中使用
  • 邮箱手机号脱敏
  • 【乐企文件生成工程】根据特定要素动态选择需要生成的发票板式文件实现
  • dolphinscheduler服务RPC心跳机制之实现原理与源码解析
  • 华为管理变革之道:管理制度创新
  • 【连续学习之SSL算法】2018年论文Selfless sequential learning
  • 在 Ubuntu 上搭建 MinIO 服务器
  • thingjs 基础案例整理
  • vulnhub靶场-jangow-01-1.0.1(截止至获取shell)
  • 《Web 项目开发之旅》
  • 工厂+策略模式之最佳实践(疾病报卡维护模块API设计)
  • 复合机器人:开启智能制造新时代
  • 单例模式的写法
  • IOS safari 播放 mp4 遇到的坎儿
  • QT + FFMPEG实现简易播放器
  • Django 管理界面中注册和配置 ECSCluster 模型
  • 第T4周:TensorFlow实现猴痘识别(Tensorboard的使用)
  • 如何实现底部导航栏
  • springboot478基于vue全家桶的pc端仿淘宝系统(论文+源码)_kaic
  • Log4j2的Policies详解、SizeBasedTriggeringPolicy、TimeBasedTriggeringPolicy
  • Qt 模型Model/视图View/代理Delegate
  • 解锁 Claude 的无限潜力:Prompt Engineering 从入门到精通
  • 游戏开发线性空间下PS工作流程