字符串 | 344.反转字符串、541.反转字符串II、剑指Offer 05.替换空格、151.翻转字符串里的单词、剑指Offer58-II.左旋转字符串

344.反转字符串

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

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

题目链接:https://leetcode.cn/problems/reverse-string/ 

思路: 本题使用双指针法,两个指针分别指向左右元素,交换元素后继续向中间移动指针即可完成。

代码:(参考:代码随想录) 

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 个字符,其余字符保持原样。

题目链接:https://leetcode.cn/problems/reverse-string-ii/ 

思路:本题仍然使用上一题双指针法交换元素的方法,在判断每计数至 2k 个字符时,可以直接将循环的步长设为2k。

代码: (参考:代码随想录

class Solution {
    public String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        // 1. 每隔 2k 个字符的前 k 个字符进行反转
        for (int i = 0; i < ch.length; i += 2 * k) {
            // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
            if (i + k <= ch.length) {
                reverse(ch, i, i+k-1);
                continue;
            }
            // 3. 剩余字符少于 k 个,则将剩余字符全部反转
            reverse(ch, i, ch.length-1);
        }
        return new String(ch);
    }

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

剑指Offer 05.替换空格

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

题目链接:https://leetcode.cn/problems/ti-huan-kong-ge-lcof/ 

思路:本题可以先判断字符串是否为null或者长度为0,之后扩容数组至空格已经替换后的大小,然后再用双指针法,左指针指向原始字符串最后一个位置,右指针指向扩容后的字符串数组的最后一个位置,当左指针没有指向空格时,将左指针的内容赋给右指针,当左指针指向空格时,填充"%20"。

代码:(来源:代码随想录 )

class Solution {
    public String replaceSpace(String s) {
        if (s == null || s.length() == 0) {
            return s;
        }
        //扩充空间,空格数量2倍
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ' ') {
                sb.append("  ");
            }
        }
        //若是没有空格直接返回
        if (sb.length() == 0) {
            return s;
        }
        //有空格情况 定义两个指针
        int left = s.length() - 1;    //左指针:指向原始字符串最后一个位置
        s += sb.toString();
        int right = s.length() - 1;    //右指针:指向扩展字符串的最后一个位置
        char[] ch = s.toCharArray();
        while (left >= 0) {
            if (ch[left] == ' ') {
                ch[right--] = '0';
                ch[right--] = '2';
                ch[right] = '%';
            } else {
                ch[right] = ch[left];
            }
            left--;
            right--;
        }
        return new String(ch);
    }
}
    

151.翻转字符串里的单词

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

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

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

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

题目链接:https://leetcode.cn/problems/reverse-words-in-a-string/ 

思路: 先去除多余的空格,再反转整个字符串,最后反转各个单词,将这三个步骤分别写成三个方法。去除多余空格时,使start指针指向开头,end指针指向末尾,在遇到空格时向中间移动。然后将剩余字符读入StringBuilder,在遇到单词之间的第一个空格时也将空格读入。反转字符串方法与本篇文章前两题中的反转字符串方法相同。最后反转各个单词,在end指针指到空格时反转空格前面的字符,然后将start指针移动到空格后,将end指针移动到start指针后,继续循环,遍历整个StringBuilder。

代码:(来源:代码随想录 )

class Solution {
   /**
     * 不使用Java内置方法实现
     * <p>
     * 1.去除首尾以及中间多余空格
     * 2.反转整个字符串
     * 3.反转各个单词
     */
    public String reverseWords(String s) {
        // System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
        // 1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        // 2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }

    private StringBuilder removeSpace(String s) {
        // System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
        int start = 0;
        int end = s.length() - 1;
        while (s.charAt(start) == ' ') start++;
        while (s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while (start <= end) {
            char c = s.charAt(start);
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            start++;
        }
        // System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
        return sb;
    }

    /**
     * 反转字符串指定区间[start, end]的字符
     */
    public void reverseString(StringBuilder sb, int start, int end) {
        // System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
        // System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
    }

    private void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 1;
        int n = sb.length();
        while (start < n) {
            while (end < n && sb.charAt(end) != ' ') {
                end++;
            }
            reverseString(sb, start, end - 1);
            start = end + 1;
            end = start + 1;
        }
    }
}

剑指Offer58-II.左旋转字符串

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

题目链接:https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/ 

思路:本题与上一题思路有些类似,同样可以先反转部分字符串再反转整个字符串。可以先反转前k个字符串,然后反转第k+1到最后一个字符串,最后整体反转。反转的方法依然是前几题使用的反转字符串方法。 

代码: (参考:代码随想录) 

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] ch = s.toCharArray();
        reverse(ch, 0, n-1);
        reverse(ch, n, s.length() - 1);
        reverse(ch, 0, s.length() - 1);
        return new String(ch);
    }

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值