代码随想录第七天(541、剑指05)

文章目录

  • 541. 反转字符串 II
    • 发现了三个基础知识的问题
    • 看答案改进
  • 剑指 Offer 05. 替换空格
    • 答案方法1
    • 答案方法2
    • 知识点
      • 一、
      • 二、
      • 三、
  • 总结

541. 反转字符串 II

发现了三个基础知识的问题

第一个

这个题目发现了一个非常大的问题,有点不知道自己的Java基础到底有多少窟窿要去补……太可怕了
一开始我写的代码中对字符串的长度的写法是:
代码随想录第七天(541、剑指05)_第1张图片
然后出现错误提示:
代码随想录第七天(541、剑指05)_第2张图片
这个时候我发现,正确的写法应该是:

int length=s.length();

因为length是一个方法啊!你如果不加括号,那和一个属性怎么区分呢?


第二个

在反转数组时,想对数组中的元素进行交换操作,我写的是:
代码随想录第七天(541、剑指05)_第3张图片
但是提示错误:
代码随想录第七天(541、剑指05)_第4张图片
也就是说,字符串不能像字符数组一样访问数组中的某个元素,字符串不是数组,想要进行这种操作,需要先将字符串转换为字符数组,用字符串的toCharArray()方法,然后字符数组转换为字符串,比较简单,可以直接new:

char[] c=new char[]{'a','b','c'};
String str=new String(c);

第三个
一开始我在写代码的过程中,检查了很多遍,都没有问题,但是就是结果不对,后来发现是对字符串的知识掌握不牢固,在自定义方法中是相对字符串元素进行交换,但是如果这是不产生一个新的字符串来存储交换后的内容而是直接输出方法中的形参的字符串,字符串并不会改变,因为字符串在底层是由数组存储的,而数组具有不变性。
错的代码:

class Solution {
    public String reverseStr(String s, int k) {
        int length=s.length();
        if(length=k&&length<2*k){
            return reverse(s,0,k-1);
        }else{
            int num=0;
            while(num0){
                reverse(s,num,length-1);//不正确,首先s此时还是
                //没有交换的字符串,其次,应该直接在语句前面加上return,
                //不然新的字符串根本没机会返回
            }
            if((length-num)>=k&&(length-num)<2*k){
                reverse(s,num,num-1);//不正确,同上
            }
            return s;//目前返回的是老的字符串,根本没有进行任何改变
        }
    }
    
    public String reverse(String s,int start,int end){
        char temp;
        int length=end-start+1;
        char[] c=s.toCharArray();
        for(int i=0;i<(int)(length/2);i++){
            temp=c[start+i];
            c[start+i]=c[end-i];
            c[end-i]=temp;
        }
        return new String(c);//这里返回的是新的字符串
    }
}

正确的:

class Solution {
    public String reverseStr(String s, int k) {
        int length=s.length();
        if(length=k&&length<2*k){
            return reverse(s,0,k-1);
        }else{
            int num=0;
            while(num0){
                return reverse(s,num,length-1);
            }
            if((length-num)>=k&&(length-num)<2*k){
                return reverse(s,num,num-1);
            }
        }
        return s;
    }
    
    public String reverse(String s,int start,int end){
        char temp;
        int length=end-start+1;
        char[] c=s.toCharArray();
        for(int i=0;i<(int)(length/2);i++){
            temp=c[start+i];
            c[start+i]=c[end-i];
            c[end-i]=temp;
        }
        return new String(c);
    }
}

看答案改进

答案的意思是,因为题目有很多相似的处理过程,可以考虑对for循环进行一个修改,答案的代码真简单,厉害
主要省代码的地方就是,在end这个指针的处理上,即判断剩下的节点还够不够k个
答案简化思路:先设置一个头指针,每次for循环都加上2k个,然后指定尾指针,尾指针是根据头指针+k个-1的位置大小和字符数组最后一个元素的位置大小进行比较,取最小值,然后判断头指针和为指针的大小来决定是否进入循环,循环中是交换两个元素,不管情况怎样,最后返回一个新建的字符串

但在写代码过程中,又发现了一个问题,就是对数组来说,如果写成:
在这里插入图片描述
会报错:
代码随想录第七天(541、剑指05)_第5张图片
也就是说,数组中是没有length这个方法的,因为他根本就不是一个类,而是基本数据类型,所以根本就没有方法,数组的工具类是Arrays,不过就算是数组的工具类,也没有length这个方法!因为length是数组中的一个属性,根本不用方法就可获得

根据答案思路改写的代码:

public String reverseStr(String s, int k) {
        char[] c=s.toCharArray();
        int start,end;
        for(int i=0;i

剑指 Offer 05. 替换空格

答案方法1

class Solution {
    public String replaceSpace(String s) {
        if(s==null||s.length()==0){
            return s;
        }
        StringBuilder sb=new StringBuilder();
        for(int i=0;i

答案方法2

class Solution {
    public String replaceSpace(String s) {
        if(s==null||s.length()==0){
            return s;
        }
        StringBuilder sb=new StringBuilder();
        for(int i=0;i

知识点

一、

一开始做这个题,想到了用字符串的方法:replaceAll(),然后又碰到了一个小问题,就是:
代码随想录第七天(541、剑指05)_第6张图片
出现错误:
在这里插入图片描述
说明不能前面是字符,后面是字符串,前面既使用字符串的双引号,中间也可以只放一个字符,但是如果两个一个用单引号,一个用双引号,就出错,因为这个方法的两个参数都是字符串类型的:
在这里插入图片描述

二、

1、这个题看答案中都用到了StringBuilder,而且都用到了Stringbuilder的toString()方法,这个方法返回的是字符串,也就是返回的是StringBuilder中的具体内容
2、在答案的方法1中用到了charAt()方法,这个方法是String中的,返回的是char型,所以要注意两边的 类型要一致,一开始写成了:
代码随想录第七天(541、剑指05)_第7张图片
出现错误:
代码随想录第七天(541、剑指05)_第8张图片
都是因为类型不匹配造成的,首先第一个错误是左边是一个char,基本数据类型,这时 = = == ==比较的就是具体的值,而引用数据类型比较的是地址
第二个左边是一个String,右边是一个字符,不能这样赋值

三、

答案方法2中用到了双指针方法,思想是:先通过新建一个空间为将空格替换为%20后大小的字符串,将新的字符串和旧的字符串合并之后赋给s,然后一个指针指向原来的带有空格的旧字符串的末尾索引,一个指向新的空的字符串的末尾索引,然后两个指针一起移动,如果旧的字符串中是空格,新的字符串中就加入% 2 0,然后两个指针前移……(前提是已经转换成了字符数组),这时选择前移是因为,就的字符串在开头部分,而如果要将就的字符串中的空格改成%20,就需要将空格后的部分后移。

其实这个题也可以从头开始添加,这种情况需要不将两个字符串合并,这时不用后移元素,直接向后一个个添加即可

字符串转换为字符数组时使用toCharArray()方法,将StringBuilder转换为char数组,可以先通过用toString()方法,将StringBuilder转换为String,然后再转换

总结

1、数组中的属性有length,直接写s.length==0即可,但是String中没有这个属性,只有方法,所以是s.length()==0
2、在基本数据类型中 = = == ==比较的是具体值,而引用数据类型中比较的是地址值,比较内容的话要用重写后的equals()方法,而String中已经重写过了
3、几个方法:
String中的toCharArray():将String转换为char数组
new String(ch):将char数组的内容新建成一个字符串
String中的toString():返回一个字符串
String中的charAt(i):找String中的索引为i的元素
String中的replaceAll(a,b):参数两个都是String类型
StringBuilder中的toString():返回一个字符串,可将StringBuilder转换为String
4、String的不变性:
如果在传入String 的s后,对s进行修改,改完后没有将修改后的字符串赋给s,而是直接将sreturn,这时的s和原来的没有改变,这也是这两个题中,在return时,基本上都是:return new String(ch); 的原因

你可能感兴趣的:(leetcode,算法,数据结构,leetcode)