项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

本博主被问到一个这样的问题:
给定一个字符串"abcdefg",要求把字符串前面的若干个字符,比如3个字符,即"abc"移动到字符串的末尾,最后的字符串变为"defgabc"。

解法一

玩数据的同学习惯用python,如果用python的话,这个问题自然没有太多技术含量,分分钟搞定的节奏。因为python处理各种字符串的方便程度,实在是令你想不到用其他方式去解决。

def invert_str(n):raw_str = "abcdefg"ret_str = raw_str[n:] + raw_str[0:n]print "ret_str is: " + ret_strinvert_str(3)

结果为:

ret_str is: defgabc

利用python里的字符串切片,确实实现起来很简单。但是如果是作为一个算法题考察的话,这种代码显然是不符合要求的。so,从时间复杂度与空间复杂度的角度再考虑这个问题。

解法二 空间复杂度小

如果要求空间复杂度比较小,可以用下面的解法。每次将需要移动的字符一个一个移动到字符串的尾部,so code如下

def leftShitMethod(list_str,n):tmp = list_str[0]#注意是从1开始,而不是0for i in xrange(1,n):list_str[i-1] = list_str[i]list_str[n-1] = tmpdef violenceMethod(m):raw_str = "abcdefg"list_str = list(raw_str)length = len(list_str)while m:leftShitMethod(list_str, length)m -= 1ret_str = "".join(list_str)print "now ret_str is: ",ret_strviolenceMethod(3)

代码运行结果

now ret_str is:  defgabc

leftShitMethod方法是每次将第一个字符移到字符串最后,每次移动的的复杂度为O(n)。移动m个字符的话,总复杂度为O(n*m)。空间复杂度为O(1),只开辟了一个tmp单元存储第一个字符。

有没有时间复杂度更低的方法勒

3.时间复杂度更低的方式

如果我们将一个字符串分成XXX与YYY两部分 ,做如下定义:
假设X="abc"X="abc"X="abc",XT="bca"X^T = "bca"XT="bca",则
(XTYT)T=YX(X^TY^T)^T=YX(XTYT)T=YX
看到这个式子同学们想到了什么,对嘛,跟矩阵的转置是一样一样的嘛。
例如,源字符串为"abcdefg",将"abc"移到末尾
则X="abc"X="abc"X="abc",Y=defgY=defgY=defg, XT="cba"X^T="cba"XT="cba",YT=gfedY^T=gfedYT=gfed,XTYT=defgabcX^TY^T=defgabcXTYT=defgabc

原理解释到此,接下来看代码

def swap_char(list_str,begin,end):while begin < end:list_str[begin],list_str[end] = list_str[end],list_str[begin]begin += 1end -= 1def invert_str_recursive(n):raw_str = "abcdefg"list_str = list(raw_str)length = len(raw_str)swap_char(list_str,0,n-1) #反转前面的部分swap_char(list_str,n,length-1) #反转后面的部分swap_char(list_str,0,length-1) #反转整个部分ret_str = "".join(list_str)print "ret_str is: ",ret_strinvert_str_recursive(3)

代码运行结果

ret_str is:  defgabc

可以看出,此方法的时间复杂度为O(n),空间复杂度为O(1)!

4.变形一

编写程序,在原字符串中把字符串尾部的m个字符移动到字符串的头部。例如:
输入为"Ilovecoding",将尾部6个字符移到前面,则输出为"codingIlove"

def swap_char(list_str,begin,end):while begin < end:list_str[begin],list_str[end] = list_str[end],list_str[begin]begin += 1end -= 1def invert_back(n):raw_str = "Ilovecoding"list_str = list(raw_str)length = len(list_str)swap_char(list_str,0,length-n-1)swap_char(list_str,length-n,length - 1)swap_char(list_str,0,length-1)ret_str = "".join(list_str)print "ret_str is: ",ret_strinvert_back(6)

运行结果

ret_str is:  codingIlove

5.变形2

题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
例如:输入"I’m like coding.",输出"coding. like I’m"

def swap_char(list_str,begin,end):while begin < end:list_str[begin],list_str[end] = list_str[end],list_str[begin]begin += 1end -= 1def invert_word():raw_sentence = "I'm like coding."list_str = list(raw_sentence)swap_char(list_str,0,len(raw_sentence)-1)tmp_each_word = []ret = ""for i in xrange(len(list_str)):if list_str[i] != " ":tmp_each_word.append(list_str[i])else:swap_char(tmp_each_word,0,len(tmp_each_word)-1)ret += "".join(tmp_each_word)ret += " "tmp_each_word = []#处理最后一个单词if i == len(list_str)-1:swap_char(tmp_each_word,0,len(tmp_each_word)-1)ret += "".join(tmp_each_word)print "ret is: ",ret

结果

ret is:  coding. like I'm

我们先颠倒句子中的所有字符。这时,不但翻转了句子中单词的顺序,而且单词内字符也被翻转了。我们再颠倒每个单词内的字符。由于单词内的字符被翻转两次,因此顺序仍然和输入时的顺序保持一致。

字符串旋转 不同解法相关推荐

  1. 字符串向左旋转的解法(c语言)

    各位大佬,今天我要介绍的是字符串旋转的解法. 该题的要求是实现一个函数,它的功能是将一个字符串向左旋转k个字节,例如: ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 它的大概思路 ...

  2. 字符串旋转——C语言

    作者简介: 博主在读计科双非本科,目前大二,正在学习JAVA,数据库,操作系统,计算机网络,数据结构,JAVA Web等- 个人主页:熬夜磕代码丶 作品专栏: 从0到1,学习算法 ⭐我变秃了,也变强了 ...

  3. C语言——字符串旋转问题

    字符串的旋转: ABCD左旋一个字符为BCDA ABCD左旋两个字符为CDAB ABCD右旋一个字符为DABC ABCD右旋两个字符为CDAB 这里只写了左旋,右旋的原理和左旋一样. 目录 实现旋转字 ...

  4. C语言---写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串

    题目: 写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串. #include <string.h> #include <stdio.h> void left_re ...

  5. 判断一个字符串是否为另外一个字符串旋转之后的字符串。

    ★判断一个字符串是否为另外一个字符串旋转之后的字符串. 例如:给定s1 = AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0. AABCD左旋一个字符得到ABCDA ...

  6. 关于字符串旋转问题的一些心得

    最近在学习编程,跟着B站一起在学习,讲了一个字符串旋转的问题,想写个博客记录一下,下面是这个题的题目. 题目内容: 实现一个函数,可以左旋字符串中的k个字符 例如: ABCD左旋一个字符得BCDA A ...

  7. 判断一个字符串是否为另外一个字符串旋转之后的字符串。 例如:给定s1 =AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0.

    题目: 判断一个字符串是否为另外一个字符串旋转之后的字符串.  例如:给定s1 =AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0. AABCD左旋一个字符得到AB ...

  8. C语言习题——字符串旋转结果

    写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串. 有两种思路: 1.每左旋一个字符,判断是否和输入的字符串相等. 2.给原字符串后面追加其本身,查找输入的字符串是否为追加后的字符串的子 ...

  9. C语言基础10——指针进阶。字符指针、指针数组、数组指针、函数指针、函数指针数组、回调函数、数组名详解、杨氏矩阵、字符串旋转

    目录 字符指针 指针数组 数组指针 数组传参.指针参数 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 练习 数组名的意义 指针笔试题 字符指针 字符指针的另一种使用方式 #include ...

  10. 两种方法判断一个字符串是否为另外一个字符串旋转之后的字符串。(C语言)...

    例如:给定s1 = AABCD和s2 = BCDAA,返回1 给定s1 = abcd和s2 = ACBD,返回0. AABCD左旋一个字符得到ABCDA AABCD左旋两个字符得到BCDAA 第一种: ...

最新文章

  1. 《PHP精粹:编写高效PHP代码》——2.1节数据持久化和Web应用程序
  2. cpu和GPU有什么区别
  3. 文件上传oss服务器
  4. 【Python】55个案例:吃透Python字符串格式化
  5. Linux系统管理技术手册——第6章 添加新用户
  6. centos7 配置虚拟交换机(物理交换机truckport设置)(使用brctl)
  7. 在.NET Core程序中设置全局异常处理
  8. 站怎么点都是一样_老鼠被卡在轮胎里,像是被点了穴道一样:这可怎么办才好?...
  9. 运算器为计算机提供了计算与逻辑,【单选题】运算器为计算机提供了计算与逻辑功能,因此称它为()....
  10. delphi版本修改PE头源码
  11. 如何利用phpize在生产环境中为php添加新的扩展php-bcmath
  12. 奔小康赚大钱 HDU - 2255(最大权值匹配 KM板题)
  13. Android包体积优化
  14. Python贝叶斯决策面计算及仿真
  15. 查看MySQL数据库占用空间大小
  16. ZYNQ-AXI DMA IP简介
  17. 科大讯飞语音开发包上手体验(1)
  18. 《让子弹飞》系列——《让子弹飞》中最大的彩蛋
  19. 2022年油猴(tampermonkey)超简单安装
  20. 树莓派3B+安装ubuntu16.04与ROS

热门文章

  1. 由input type=file /获取的file.type为空字符串引申浏览器是如何获取文件的MIME类型...
  2. mycat err:java.sql.SQLNonTransientException: find no Route:select日志报错
  3. [jquery] 图片热区随图片大小自由缩放
  4. 关于nagios 邮件报警问题
  5. 当U盘内的文件夹都成了1KB的快捷方式的解决方法
  6. 如何为ip v6设定子网
  7. Maybe it's time to go away
  8. 七类***各有“黑招”
  9. 史上最全40道dubbo面试题
  10. Webdriver常用的元素定位