• LeetCode——字符串(Java)


    简介

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

    [简单] 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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    方法②:

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    [简单] 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();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

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

    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--;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

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

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

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

    ③:StringBuilder使用一个String类型构造的时候,分配的空间不完全是String本身的长度,所以在delete操作中,删除右边空格的end边界应该是String的长度边界,而不是StringBuilder的。
    在这里插入图片描述

    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
  • 相关阅读:
    BaseBottomSheetFragment嵌套RecyclerView滑动冲突
    axios中取消请求的使用
    计算机专业毕业论文java毕业设计开题报告SSM同学录[包运行成功]
    C++ 多线程编程教程:使用 std::thread 和 std::future 进行并发任务管理 ,处理线程超时
    卡尔曼及扩展卡尔曼滤波详细推导-来自DR_CAN视频
    Postman常用断言功能解析
    唯品会商品详情API接口(item_get-获得vip商品详情接口)
    2024最新计算机设计大赛选题推荐
    转账——异步入账
    SpringCloud之NamedContextFactory
  • 原文地址:https://blog.csdn.net/jhin_lx/article/details/134426876