代码随想录算法训练营Day8 | ● 344.反转字符串● 541. 反转字符串II● 54.替换数字● 151.翻转字符串里的单词● 55.右旋转字符串

(记得重学)

● 344.反转字符串

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

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

示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

题目链接:344. 反转字符串

卡哥的视频链接:字符串基础操作! | LeetCode:344.反转字符串

题目思考:和反转链表相似,但是要简单一些

代码示例:

终于有我能一次性直接写出来的题了哈哈哈哈哈哈

代码详解:

  1. 首先,定义了两个变量 leftright,分别表示字符数组的左右两个指针。left 指向数组的第一个字符,而 right 指向数组的最后一个字符。

  2. while 循环中,不断执行以下操作,直到 left 指针大于等于 right 指针:

    • 首先,创建一个临时变量 temp,用于暂存 left 指针指向的字符。
    • 然后,将 right 指针指向的字符赋值给 left 指针指向的位置,实现字符交换。
    • 接着,将 temp 中暂存的字符赋值给 right 指针指向的位置,实现字符交换。
    • 最后,分别将 left 指针和 right 指针向中间移动一位,继续进行下一轮的字符交换。
  3. left 指针不再小于 right 指针时,说明字符数组的所有字符都已经完成了翻转操作,整个循环结束。

这段代码利用了双指针的思想,从字符串的两端开始,逐步向中间移动,交换对应位置上的字符,从而实现了字符串的翻转。这样的算法复杂度为 O(n/2),其中 n 是字符数组的长度。

leetcode提交记录:

小tips:

1.注意数组类型是字符型,新定义temp值的时候别忘了嗷!

2.当right是n时,代表剩下的已经不足k了,则全部交换,当right是i + k时,说明长度在k到2k之间,则转换 i 到 i + k这一部分

● 541. 反转字符串II

题目:给定一个字符串 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
题目链接:541. 反转字符串 II

卡哥的视频链接:字符串操作进阶! | LeetCode:541. 反转字符串II

题目思考:当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。

其实我们要交换的就是i+k这一段的字符串

代码示例:
public class swap_k {
    public String reverseStr(String s,int k){
        int n = s.length();
        char[] c = s.toCharArray();
        //有时候固定要往前走多少格的时候,可以在for循环上做做文章
        for (int i = 0; i < n; i += 2*k) {
           reverse(c,i,Math.min(i + k,n) - 1);
            }
        return new String(c);
        }
        public void reverse(char[] arr,int left , int right){
        while(left < right){
            char temp = arr[left];
            arr[right] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}

代码逻辑详解:

  1. 首先,定义了一个 reverseStr 方法,接受两个参数:字符串 s 和整数 k,表示每隔 k 个字符进行反转。

  2. 在方法内部,首先获取字符串 s 的长度,并将其赋值给变量 n

这段代码利用了双指针的思想和循环遍历数组的方法,以较低的时间复杂度 O(n) 实现了对字符串每隔 k 个字符进行反转。

  • 然后,将字符串 s 转换为字符数组 arr,以便后续操作。

  • 接下来,通过一个 for 循环以步长为 2 * k 遍历字符数组 arr,每次迭代都会处理从 i 开始的 k 个字符的反转。这样可以确保每隔 k 个字符进行反转。

  • 在每次迭代中,调用名为 reverse 的辅助方法,实现对指定子数组的反转操作。reverse 方法接受三个参数:字符数组 arr、反转区间的起始位置 left、反转区间的结束位置 right

  • reverse 方法中,使用双指针法对指定子数组进行反转操作:

    • 初始化左指针 left 和右指针 right,分别指向指定子数组的首尾位置。
    • while 循环中,当 left 指针小于 right 指针时,执行以下操作:
      • left 指针指向的字符与 right 指针指向的字符进行交换。
      • 分别将 left 指针和 right 指针向中间移动一位。
    • left 指针不再小于 right 指针时,说明指定子数组的所有字符都已完成反转操作,循环结束。
  • 每次迭代完成后,整个字符串 s 中每隔 k 个字符的子串都完成了反转操作。

  • 最后,将字符数组 arr 转换回字符串,并将结果返回。

leetcode提交记录:

小tips:

1.注意此题所交换的是字符,定义新变量的时候要注意!

● 54.替换数字

题目:假定一段路径记作字符串 path,其中以 "." 作为分隔符。现需将路径加密,加密方法为将 path 中的分隔符替换为空格 " ",请返回加密后的字符串。

示例 1:

输入:path = "a.aef.qerf.bb"

输出:"a aef qerf bb"

题目链接:LCR 122. 路径加密

题目思考:因为String不可以修改,所以只能申请一段新的空间

代码示例:

● 151.翻转字符串里的单词

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

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

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

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

示例 1:

输入:s = “the sky is blue”
输出:“blue is sky the”

示例 2:

输入:s = " hello world "
输出:“world hello”
解释:反转后的字符串中不能存在前导空格和尾随空格。

示例 3:

输入:s = “a good example”
输出:“example good a”
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

题目链接:151. 反转字符串中的单词

卡哥的视频链接:字符串复杂操作拿捏了! | LeetCode:151.翻转字符串里的单词

                                                                                                                                                                                                                                                                                          

代码示例:

   public String reverseWords(String s) {
            s = s.trim();                                    // 删除首尾空格
            int j = s.length() - 1, i = j;
            StringBuilder res = new StringBuilder();
            while (i >= 0) {
                while (i >= 0 && s.charAt(i) != ' ') i--;     // 搜索首个空格
                res.append(s.substring(i + 1, j + 1) + " "); // 添加单词
                while (i >= 0 && s.charAt(i) == ' ') i--;     // 跳过单词间空格
                j = i;                                       // j 指向下个单词的尾字符
            }
            return res.toString().trim();                    // 转化为字符串并返回
        }

代码逻辑详解:

  1. 方法内首先对输入的字符串 s 进行了去除首尾空格的操作,使用了 trim() 方法。

  2. 然后,定义了两个变量 ij,它们分别表示当前单词的末尾位置和起始位置,初始值都为字符串末尾的索引值 s.length() - 1

  3. 创建了一个 StringBuilder 对象 res,用于存储反转后的结果。

  4. 进入一个 while 循环,条件是 i >= 0,即当字符串还有字符时持续执行反转操作。

  5. 在循环中,首先判断当前字符是否为空格,如果不是空格则向前移动 i,直到遇到空格为止。这样就找到了一个完整的单词。

  6. 将找到的单词从字符串中提取出来,使用 substring() 方法从索引 i + 1 到索引 j 提取出子字符串,并将其追加到 res 中,同时在末尾添加一个空格,确保单词之间有空格分隔。

  7. 继续向前寻找下一个单词,重复上述步骤,直到遍历完整个字符串。

  8. 最后,使用 res.toString().trim() 将 StringBuilder 对象转换为字符串,并去除首尾空格,返回反转后的结果。

这段代码实现了对输入字符串中的单词顺序进行反转,并且正确处理了单词之间的空格。

leetcode提交记录:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值