每日一题:反转字符串

443 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

反转字符串|

力扣题目链接

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

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

示例 1:

输入:s = ["h","e","l","l","o"]

输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]

输出:["h","a","n","n","a","H"]

提示:

  • 1 <= s.length <= 105
  • s[i] 都是 ASCII 码表中的可打印字符

解题思路:双指针

思路很简单,使用左右指针就可以

两个指针分别位于数组的索引处,对于字符串来说

  • 左指针left从数组的第一个元素的位置出发,向后移动
  • 右指针right从数组的最后一个元素的位置出发,向前移动
  • 左右指针同时向中间移动,交换元素

代码:(JAVA实现)

public void reverseString(char[] s) {
        if (s.length == 0 || s == null) {
            return;
        }

        int left = 0;
        int right = s.length-1;

        //交换元素
        while (left < right) {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;

            //缩小区间
            left++;
            right--;
        }
    }

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

提交结果

image.png

反转字符串||

力扣题目链接

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

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

示例 1:

输入: s = "abcdefg", k = 2
输出: "bacdfeg"

示例 2:

输入: s = "abcd", k = 2
输出: "bacd"

提示:

  • 1 <= s.length <= 104
  • s 仅由小写英文组成
  • 1 <= k <= 104

解题思路

这道题的思路就是:在遍历字符串的过程中,起始值每次移动 2*K 的长度,然后判断是否有要反转的区间

每次要找的就是 2*k 区间的起点

我们只要把这个字符串拆分成固定规律的一段一段地进行判断

代码:(JAVA实现)

    public String reverseStr(String s, int k) {
        StringBuffer res = new StringBuffer();

        int start = 0;
        int length = s.length();

        //确定k处和2k处
        while (start < length) {
            StringBuffer temp = new StringBuffer();
            
            //与length进行比较 只要大于length了 就重置成length
            int firstK = (start + k > length) ? length : (start + k);
            int secondK = (start + (2 * k) > length) ? length : (start + 2 * k);
            
            //把要反转的区间取出来
            temp.append(s.substring(start,firstK));
            //这里我用reverse方法来实现了区间里值的反转,他和我们自己写的反转作用是一样的,再将反转后的值添加到res里
            res.append(temp.reverse());

            //如果firstK到secondK之间有元素,这些元素直接放入res里即可。
            if (firstK < secondK) { //此时剩余长度一定大于k。
                res.append(s.substring(firstK,secondK));
            }

            //移动要判断段的启始位置
            start += (2 * k);
        }
        return res.toString();
    }

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

提交结果

image.png