代码随想录LeetCode刷题第五天---------344. 反转字符串541. 反转字符串 II替换空格151. 反转字符串中的单词

344. 反转字符串

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

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

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

  • 思路:我首先讲到的就是交换,依次收尾交换

错误代码:

class Solution {
    public void reverseString(char[] s) {
    for(int i=0,j= s.length-1;i<s.length/2;i++,j--){
            char temp = 'a';
            temp=s[i];
            s[i]=s[j];
            s[j]=temp;
        }
    }
}

不知道为啥,没有通过所有用例,原来是i

541. 反转字符串 II

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

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

示例 1:

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

  • 思路:根本没看懂题呢,然后看懂题了,但是规则有点复杂,没能模拟出来。其实想到了i+=2k,但没有想明白边界调节怎么处理的,这个题看了题解才会

错误代码

class Solution {
    public String reverseStr(String s, int k) {
        char[] a = s.toCharArray();
        int n = a.length;
        for(int i=0;i<a.length;i+=2*k){
            if(n-i>=k){
                reverse(a,i,i+k);
            }else{
                reverse(a,i,n-1);
                //第一处错误,下面方法里直接h-1了,这就直接是n
            }
        }
       return String.valueOf(a);
    }

    public void reverse(char[] s,int q,int h){
        for(int i=q,j=h-1;i<=(h-1-q)/2;i++,j--){
        //第二处错误,i<=(h-1-q)/2如果数组的起始点一直不变可以这么判断,那i也不一直从0起加啊,人家i是从q起加,直接用i
            char temp = 'a';
            temp=s[i];
            s[i]=s[j];
            s[j]=temp;
        }
    }
    }

正确代码

class Solution {
    public String reverseStr(String s, int k) {
        char[] a = s.toCharArray();
        int n = a.length;
        for(int i=0;i<a.length;i+=2*k){
            if(n-i>=k){
                reverse(a,i,i+k);
            }else{
                reverse(a,i,n);
            }
        }
       return String.valueOf(a);
    }

    public void reverse(char[] s,int q,int h){
        for(int i=q,j=h-1;i<j;i++,j--){
            char temp = 'a';
            temp=s[i];
            s[i]=s[j];
            s[j]=temp;
        }
    }
    }

剑指 Offer 05. 替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”

思路:首先想到的就是String的方法replace,可以正常运行

class Solution {
    public String replaceSpace(String s) {
        String s11 = s.replace(" ", "%20");
        return s11;
    }
}

但作为考点 这样不好,可以用下面的方法

  • 自己的错代码
class Solution {
    public String replaceSpace(String s) {
        char[] a = new char[s.length()*3];
        for(int i=0,j=0;j>=s.length();i++,j++){
        //判断条件是小于大哥!
            if(s.charAt(j)==' '){
                a[i]='%';
                a[i+1]='2';
                a[i+1+1]='0';
                i+=2;
            }else{
                a[i]=s.charAt(j);
            }
        }
        return String.valueOf(a);
    }
}

错了,输出一堆乱七八糟的/u00000,整半天发现,真的离谱,String.valueOf的后面 如果数组大的话会出现一堆u/0000,在这编译不通过,但是在控制台是可以的,这是就要控制准确数组的的大小
或者使用题解的方式String newStr = new String(array, 0, size);,题解的方式不太好想到,不知道String还有有这种new的方式,一般String的new的方式就是String str = new String(charArray),但是这种用于本题的话还是/u00000

  • 自己题解
class Solution {
    public String replaceSpace(String s) {
        char[] a = new char[s.length()*3];
        int size =0;
        for(int i=0,j=0;j<s.length();i++,j++){
            if(s.charAt(j)==' '){
                a[i]='%';
                a[i+1]='2';
                a[i+1+1]='0';
                i+=2;
            }else{
                a[i]=s.charAt(j);
            }
            size=i+1;
        }

        char[] b = new char[size];
        for(int i=0;i<size;i++){
            b[i]=a[i];
        }
        return String.valueOf(b);
    }
}
  • 官方题解
class Solution {
    public String replaceSpace(String s) {
        int length = s.length();
        char[] array = new char[length * 3];
        int size = 0;
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            if (c == ' ') {
                array[size++] = '%';
                array[size++] = '2';
                array[size++] = '0';
            } else {
                array[size++] = c;
            }
        }
        String newStr = new String(array, 0, size);
        return newStr;
    }
}

151. 反转字符串中的单词

思路:当前的思路就是首先先遍历字符串,遍历到空格时就把空格前面的字母存在string[i]里(不知道怎们实现),如果空格前面是空格或者是null的话,就不管。转成String数组后,数组里的每一个元素应该都是一个单词,然后reverse单词,最后带着空格输出就行了。

未实现

另一种思路:先去掉多余的空格,然后翻转每个单词,最后翻转整个字符串,最后是自己琢磨出来了,感觉这个题做了2-3个小时,一直在改,在想,但又钻牛角尖不想看题解,烧脑啊家人们,后来看题解也很长,懒得往下看

自己正确的题解

class Solution {
    public String reverseWords(String s) {
        StringBuffer a = new StringBuffer();
        for(int i=0;i<s.length();i++){
        //这里是在处理空格
            if(i==0&&s.charAt(i)==' '){
            }else{
                if(s.charAt(i)!=' '){
                    a.append(s.charAt(i));
                }else if(s.charAt(i)==' '&&s.charAt(i-1)!=' ') {
                    a.append(s.charAt(i));
                }else if(s.charAt(i)==' '&&s.charAt(i-1)==' '){
                }
            }
        }
        if(s.charAt(s.length()-1)==' '){
        //如果给的字符串最后有空格的话,这样就多了一个结尾部分的空格,所以删掉
            a.delete(a.length()-1, a.length());
        }
        return reverse(a.toString().toCharArray());
    }

    public String reverse(char[] sb){
        int j=0;
        for(int i=0;i<sb.length;i++){
            if(sb[i]==' '){
                char tep = ' ';
                for(int w=j,o=i-1;w<o;w++,o--){
                    tep = sb[w];
                    sb[w]=sb[o];
                    sb[o]=tep;
                }
                j=i+1;
            }else if(i==sb.length-1){
                char tep = ' ';
                for(int w=j,o=i;w<o;w++,o--){
                    tep = sb[w];
                    sb[w]=sb[o];
                    sb[o]=tep;
                }
            }
        }
        for (int i = 0,p=sb.length-1; i < p; i++,p--) {
            char tep = ' ';
                tep = sb[i];
                sb[i]=sb[p];
                sb[p]=tep;
        }
        return String.valueOf(sb);
    }
}

看了题解啦!!去掉多余空格那里我用了for循环,题解是加加减减。
其实是能优化的,就是把reverse方法写死,多传递两个参数表示reverse的边界,这样就不用判断最尾了,直接用就行
另外,题解这里做了我刚才考虑到StringBuffer怎么交换值的方法,使用setCharAt(索引,值),只能交换一个char字符,如下所示,因此就不用麻烦转成char数组来交换值了

 public void reverse(StringBuilder sb, int left, int right) {
        while (left < right) {
            char tmp = sb.charAt(left);
            sb.setCharAt(left++, sb.charAt(right));
            sb.setCharAt(right--, tmp);
        }
    }
  • 官方题解
class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = trimSpaces(s);
        reverse(sb, 0, sb.length() - 1);
        reverseEachWord(sb);
        return sb.toString();
    }

    public StringBuilder trimSpaces(String s) {
        int left = 0, right = s.length() - 1;
        while (left <= right && s.charAt(left) == ' ') {
            ++left;
        }
        while (left <= right && s.charAt(right) == ' ') {
            --right;
        }
        StringBuilder sb = new StringBuilder();
        while (left <= right) {
            char c = s.charAt(left);

            if (c != ' ') {
                sb.append(c);
            } else if (sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }

            ++left;
        }
        return sb;
    }

    public void reverse(StringBuilder sb, int left, int right) {
        while (left < right) {
            char tmp = sb.charAt(left);
            sb.setCharAt(left++, sb.charAt(right));
            sb.setCharAt(right--, tmp);
        }
    }

    public void reverseEachWord(StringBuilder sb) {
        int n = sb.length();
        int start = 0, end = 0;

        while (start < n) {
            // 循环至单词的末尾
            while (end < n && sb.charAt(end) != ' ') {
                ++end;
            }
            // 翻转单词
            reverse(sb, start, end - 1);
            // 更新start,去找下一个单词
            start = end + 1;
            ++end;
        }
    }
}


你可能感兴趣的:(leetcode,算法,java)