代码随想录算法训练营第八天 | 字符串部分算法题

344.反转字符串

力扣题目链接

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

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

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

解法:直接用双指针解决,简单

class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length - 1;
        while (left < right) {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left ++;
            right --;
        } 
    }
}

541. 反转字符串II

力扣题目链接

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

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

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

示例:

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

class Solution {
    public String reverseStr(String s, int k) {
        int start = 0, end;
        // 剩余字符大于2k的情况
        while (start <= s.length() - 2 * k) {
            end = start + k - 1;
            s = reverse(s, start, end);
            start += 2 * k;
        };
        // 如果剩余字符少于 k 个,则将剩余字符全部反转。
        if (s.length() - start < k) {
            end = s.length() - 1;
            s = reverse(s, start, end);
        }
        // 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
        if (k <= s.length() - start && s.length() - start < 2 * k) {
            end = start + k - 1;
            s = reverse(s, start, end);
        }
        return s;
    }
    // 反转字符串
    private String reverse(String s, int left, int right) {
        char[] charArray = s.toCharArray();
        while (left < right) {
                char temp = charArray[left];
                charArray[left] = charArray[right];
                charArray[right] = temp;
                left ++;
                right --;
        }
        return new String(charArray);
    }
}

剑指 Offer 05. 替换空格

[题目链接](剑指 Offer 05. 替换空格 - 力扣(Leetcode)) 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

使用StringBuilder轻松解决

class Solution {
    public String replaceSpace(String s) {
        // 使用StringBuilder解决
        if (s == null) {
            return s;
        }
        StringBuilder sb = new StringBuilder();
        for (char i : s.toCharArray()) {
            if (i == ' ') {
                sb.append("%20");
            } else {
                sb.append(i);
            }
        }
        return sb.toString();
    }
}

151.翻转字符串里的单词

[题目链接](151. 反转字符串中的单词 - 力扣(Leetcode)) 给定一个字符串,逐个翻转字符串中的每个单词。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

**注意:**输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

解法:

  1. 去掉前导空格和尾随空格
  2. 翻转整个字符串
  3. 挨个单词翻转
class Solution {
    public String reverseWords(String s) {
        // 去掉多余空白字符
        StringBuilder sb = trimSpaces(s);
        
        // 翻转字符串, 后两个参数表示参数的起始下标
        reverse(sb, 0, sb.length() - 1);
       
        // 翻转每个单词
        reverseEachWord(sb);
        
        return sb.toString();
    }

    private StringBuilder trimSpaces(String s) {
        StringBuilder sb = new StringBuilder();
        int left = 0, right = s.length() - 1;
        // 去掉前导空格
        while (s.charAt(left) == ' ' && left <= right) {
            ++left;
        }
        // 去掉尾随空格
        while (s.charAt(right) == ' ' && left <= right) {
            --right;
        }
        // 去掉单词多余空格
        while (left <= right) {
            char c = s.charAt(left);
            // 只要字符不为空或stringbuilder实例最后一个字符不是空格,stringbuilder实例就添加遍历的字符
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            ++left;
        }
        return sb;
    }

    private 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);
        }
    }

    private void  reverseEachWord(StringBuilder sb) {
        StringBuilder result = new StringBuilder();
        // 找到单词的起始下标,翻转
        int start = 0, end = 0;
        while (start < sb.length()) {
            while (end < sb.length() && sb.charAt(end) != ' ') {
                ++end;
            }
            // 翻转单词
            reverse(sb, start, end -1);
            // 更新start位置,继续寻找单词进行翻转
            start = end+1;
            end++;
        }
    }
}

剑指 Offer 58 - II. 左旋转字符串

[题目链接](剑指 Offer 58 - II. 左旋转字符串 - 力扣(Leetcode)) 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

两种解法 :

  1. 前n个字符依次存StringBuilder2, 剩余的字符依次存StringBuilder2,最后StringBuilder2 拼接 StringBuilder1;

    class Solution {
        public String reverseLeftWords(String s, int n) {
            StringBuilder sb1 = new StringBuilder();
            StringBuilder sb2 = new StringBuilder();
            for (int i = 0; i < n; i++) {
                sb1.append(s.charAt(i));
            }
            for (int i = n; i < s.length(); i++) {
                sb2.append(s.charAt(i));
            }
            return sb2.toString() + sb1.toString();
        }
    }
    
  2. 反转区间为前n的子串,再反转区间为n到末尾的子串,最后整个字符串一起翻转

    class Solution {
        public String reverseLeftWords(String s, int n) {
            StringBuilder sb = new StringBuilder(s);
            // 翻转区间为前n的子串
            reverse(sb, 0, n-1);
    
            // 翻转区间为n到末尾的子串
            reverse(sb, n, s.length() - 1);
    
            // 最后整个字符串一起翻转
            reverse(sb, 0, s.length() - 1);
    
            return sb.toString();
        }
    
        private 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);
            }
        }
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值