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

44 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

Leetcode : leetcode-cn.com/problems/zu…

GitHub : github.com/nateshao/le…

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

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

难度:简单

示例 1:

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

示例 2:

 输入: s = "lrloseumgh", k = 6
 输出: "umghlrlose"

方法一:字符串切片

Go

func reverseLeftWords(s string, n int) string {
    return s[n:] + s[:n]
}

image.png

获取字符串 s[ n : ] 切片和 s[ : n ]切片,使用 "+" 运算符拼接并返回即可。

复杂度分析:

  • 时间复杂度O(N):中N为字符串s的长度,字符串切片函数为线性时间复杂度;
  • 空间复杂度O(N) :两个字符串切片的总长度为N。

 package com.nateshao.sword_offer.topic_46_reverseLeftWords;
 ​
 /**
  * @date Created by 邵桐杰 on 2022/2/20 19:46
  * @微信公众号 千羽的编程时光
  * @个人网站 www.nateshao.cn
  * @博客 https://nateshao.gitee.io
  * @GitHub https://github.com/nateshao
  * @Gitee https://gitee.com/nateshao
  * Description:
  */
 public class Solution {
     public static void main(String[] args) {
         String s = "abcdefg";
         System.out.println("reverseLeftWords1(s,2) = " + reverseLeftWords1(s, 2));// reverseLeftWords1(s,2) = cdefgab
     }
 ​
     /**
      * 方法一:字符串切片
      * @param s
      * @param n
      * @return
      */
     public static String reverseLeftWords1(String s, int n) {
         return s.substring(n, s.length()) + s.substring(0, n);
     }
 }

方法二:列表遍历拼接

Go

func reverseLeftWords(s string, n int) string {
    ss := []byte(s)
    length := len(ss)
    var tmp []byte
    for i:=0;i<n;i++{
        tmp = append(tmp, ss[i])
    }
    ss = append(ss[n:length], tmp...)
    return string(ss)
}

image.png

若面试规定不允许使用 切片函数 ,则使用此方法。

算法流程:

  1. 新建一个StringBuilder(Java) ,记为 res ;
  2. 先向 res 添加 “第 n + 1 位至末位的字符” ;
  3. 再向 res 添加 “首位至第 n 位的字符” ;
  4. 将 res 转化为字符串并返回。
复杂度分析:
  • 时间复杂度 O(N) : 线性遍历 s 并添加,使用线性时间;
  • 空间复杂度 O(N) : 新建的辅助 res使用 O(N) 大小的额外空间。

 /**
  * 方法二:列表遍历拼接
  */
 public static String reverseLeftWords2(String s, int n) {
     StringBuilder res = new StringBuilder();
     for (int i = n; i < s.length(); i++) {
         res.append(s.charAt(i));
     }
     for (int i = 0; i < n; i++) {
         res.append(s.charAt(i));
     }
     return res.toString();
 }

方法三:字符串遍历拼接

此方法与方法二思路一致,区别是使用字符串代替列表。

复杂度分析:

  • 时间复杂度O(N) :线性遍历s并添加,使用线性时间;
  • 空间复杂度O(N) :假设循环过程中内存会被及时回收,内存中至少同时存在长度为N和N - 1的两 个字符串(新建长度为N的res需要使用前一个长度N - 1的res ,因此至少使用O(N)的额外空间。
 public String reverseLeftWords3(String s, int n) {
         String res = "";
         for (int i = n; i < s.length(); i++) {
             res += s.charAt(i);
         }
         for (int i = 0; i < n; i++) {
             res+=s.charAt(i);
         }
         return res;
     }

参考链接:leetcode-cn.com/problems/zu…

\