LeetCode——字符串(Java)

字符串

  • 简介
  • [简单] 344. 反转字符串
  • [简单] 541. 反转字符串 II
  • [中等] 151. 反转字符串中的单词

简介

记录一下自己刷题的历程以及代码。写题过程中参考了 代码随想录。会附上一些个人的思路,如果有错误,可以在评论区提醒一下。

[简单] 344. 反转字符串

原题链接

方法①:

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

方法②:

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

[简单] 541. 反转字符串 II

原题链接

一开始想到比较差的方法:就是给到一个新的StringBuilder,然后按照结果的顺序依次再加入到StringBuilder中去,时间复杂度比较高,因为对那一部分不需要转置的字符也做了处理。

public String reverseStr(String s, int k) {
        StringBuilder sb = new StringBuilder(s.length());
        int over = -1; //标记已经完成处理的下标
        for (int i = 0; i < s.length(); i++) {
            if (i - over == 2 * k) {
                for (int j = over + k; j > over; j--) {
                    sb.append(s.charAt(j));
                }
                for (int j = over + k + 1; j <= over + 2 * k; j++) {
                    sb.append(s.charAt(j));
                }
                over = over + 2 * k;
            }
        }
        if(s.length() - 1 - over < k){
            for (int j = s.length() - 1; j > over; j--) {
                sb.append(s.charAt(j));
            }
        }else{
            for (int j = over + k; j > over; j--) {
                sb.append(s.charAt(j));
            }
            for (int j = over + k + 1; j < s.length(); j++) {
                sb.append(s.charAt(j));
            }
        }
        return sb.toString();
    }

这里首先提取了反转部分的代码,看起来更清晰,同时,也避开了对不需要转换的那一部分做处理的时间复杂度,效率更高

class Solution {
    public String reverseStr(String s, int k) {
        char[] c = s.toCharArray();
        int i = 2 * k - 1;
        int n = s.length();
        for (; i < n; i += 2 * k) {
            reverse(c, i-2*k+1, i-k);
        }
        if(i-2*k+1 < n) {
            reverse(c, i - 2 * k + 1, n - 1 < i - k ? n - 1 : i - k);
        }
        return new String(c);
    }

    private void reverse(char[] c, int left, int right){
        while(left < right){
            char temp = c[left];
            c[left] = c[right];
            c[right] = temp;
            left++;
            right--;
        }
    }
}

[中等] 151. 反转字符串中的单词

原题链接
总共分三步:删除空格,整体反转,单词反转。
在这里插入图片描述
deleteSpace():删除空格,先是删除后置空格,删除前置空格,再删除中间的空格,因为中间的空格需要保留一个,与删除前置后置逻辑上不同
使用StringBuilder类的话需要注意:
①:delete函数的右边界end对应下标并不会被删除,比如sb.delete(5,8),删除的是5,6,7下标对应元素。
LeetCode——字符串(Java)_第1张图片
②:先删除前导空格的话,会导致整个字符串的所有下标都左移,不利于判断,先删除后置空格则没有这个问题。

//先删除后置再删除前置
if(r + 1 < s.length() - 1) 
    sb = sb.delete(r + 1, s.length()); //删除后置空格
if(l > 0) 
    sb = sb.delete(0, l); //删除前导空格

③:StringBuilder使用一个String类型构造的时候,分配的空间不完全是String本身的长度,所以在delete操作中,删除右边空格的end边界应该是String的长度边界,而不是StringBuilder的。
LeetCode——字符串(Java)_第2张图片

class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = deleteSpace(s);
        sb = reverse(sb, 0, sb.length()-1);
        int start = 0;
        int i = 0;
        for(; i < sb.length(); i++){
            if(sb.charAt(i) == ' '){
                sb = reverse(sb, start, i - 1);
                start = i + 1;
            }
        }
        sb = reverse(sb, start, i - 1);
        return sb.toString();
    }

    private StringBuilder deleteSpace(String s){
        int l = 0;
        int r = s.length() - 1;
        while(s.charAt(l) == ' ') l++;
        while(s.charAt(r) == ' ') r--;
        StringBuilder sb = new StringBuilder(s);
        if(r + 1 < s.length() - 1) sb = sb.delete(r + 1, s.length()); //删除后置空格
        if(l > 0) sb = sb.delete(0, l); //删除前导空格
        int i = 0;
        while(i < sb.length()){
            if(sb.charAt(i) == ' ') {
                int start = ++i;
                while (sb.charAt(i) == ' ') i++;
                int end = i;
                if (end - start >= 0) {
                    sb = sb.delete(start, end);
                    i = start;
                }
            }
            i++;
        }
        return sb;
    }

    private StringBuilder reverse(StringBuilder sb, int l, int r){
        while(l < r){
            char temp = sb.charAt(l);
            sb.setCharAt(l, sb.charAt(r));
            sb.setCharAt(r, temp);
            l++;
            r--;
        }
        return sb;
    }
}

你可能感兴趣的:(算法分析与设计,leetcode,java,算法)