1.1 旋转字符串

题目描述

给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b'移动到字符串的尾部,使得原字符串变成字符串“cdefab”。请写一个函数完成此功能,要求对长度为n的字符串操作的时间复杂度为 O(n),空间复杂度为 O(1)。

分析与解法

解法一:暴力移位法

初看此题,可能最先想到的方法是按照题目所要求的,把需要移动的字符一个一个地移动到字符串的尾部,如此我们可以实现一个函数 LeftShiftOne(char* s, int n)  ,以完成移动一个字符到字符串尾部的功能,代码如下所示:

void LeftShiftOne(char* s, int n)
{
char t = s[0]; //保存第一个字符
for (int i = 1; i < n; i++)
{
s[i - 1] = s[i];
}
s[n - 1] = t;
}

因此,若要把字符串开头的m个字符移动到字符串的尾部,则可以如下操作:

void LeftRotateString(char* s, int n, int m)
{
while (m--)
{
LeftShiftOne(s, n);
}
}

下面,我们来分析一下这种方法的时间复杂度和空间复杂度。

针对长度为n的字符串来说,假设需要移动m个字符到字符串的尾部,那么总共需要 m*n 次操作,同时设立一个变量保存第一个字符,如此,时间复杂度为O(m * n),空间复杂度为O(1),空间复杂度符合题目要求,但时间复杂度不符合,所以,我们得需要寻找其他更好的办法来降低时间复杂度。

解法二:三步反转法

对于这个问题,换一个角度思考一下。

将一个字符串分成X和Y两个部分,在每部分字符串上定义反转操作,如X^T,即把X的所有字符反转(如,X="abc",那么X^T="cba"),那么就得到下面的结论:(X^TY^T)^T=YX,显然就解决了字符串的反转问题。

例如,字符串 abcdef ,若要让def翻转到abc的前头,只要按照下述3个步骤操作即可:

  1. 首先将原字符串分为两个部分,即X:abc,Y:def;
  2. 将X反转,X->X^T,即得:abc->cba;将Y反转,Y->Y^T,即得:def->fed。
  3. 反转上述步骤得到的结果字符串X^TY^T,即反转字符串cbafed的两部分(cba和fed)给予反转,cbafed得到defabc,形式化表示为(X^TY^T)^T=YX,这就实现了整个反转。

如下图所示:

代码则可以这么写:

void ReverseString(char* s,int from,int to)
{
while (from < to)
{
char t = s[from];
s[from++] = s[to];
s[to--] = t;
}
} void LeftRotateString(char* s,int n,int m)
{
m %= n; //若要左移动大于n位,那么和%n 是等价的
ReverseString(s, 0, m - 1); //反转[0..m - 1],套用到上面举的例子中,就是X->X^T,即 abc->cba
ReverseString(s, m, n - 1); //反转[m..n - 1],例如Y->Y^T,即 def->fed
ReverseString(s, 0, n - 1); //反转[0..n - 1],即如整个反转,(X^TY^T)^T=YX,即 cbafed->defabc。
}

这就是把字符串分为两个部分,先各自反转再整体反转的方法,时间复杂度为O(n),空间复杂度为O(1),达到了题目的要求。

举一反三

1、链表翻转。给出一个链表和一个数k,比如,链表为1→2→3→4→5→6,k=2,则翻转后2→1→6→5→4→3,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→6→5,用程序实现。

2、编写程序,在原字符串中把字符串尾部的m个字符移动到字符串的头部,要求:长度为n的字符串操作时间复杂度为O(n),空间复杂度为O(1)。 例如,原字符串为”Ilovebaofeng”,m=7,输出结果为:”baofengIlove”。

3、单词翻转。输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变,句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。例如,输入“I am a student.”,则输出“student. a am I”。

程序员编程艺术:面试和算法心得-(转 July)的更多相关文章

  1. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

  2. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  3. 腾讯Java程序员第二轮面试11个问题,你会几个?

    此前,分享了阿里巴巴.网易.百度等多家名企的JAVA面试题. 这也引来了不少程序员网友们的围观. 其中,也有相当一部分网友是已经从事Java开发好多年的程序员,当他们阅读完JAVA面试题的反应是:一个 ...

  4. 第一章-第七题( 有人认为,“中文编程”, 是解决中国程序员编程效率一个秘密武器,请问它是一个 “银弹” 么? )--By 侯伟婷

    首先,“银弹”在百度百科中的解释是银色的子弹,我们更熟知的“银弹”一词,应该是在<人月神话>中提到的.银弹原本应该是指某种策略.技术或者技巧可以极大地提高程序员的生产力[1].此题目中关于 ...

  5. 程序员编程利器:20款最好的免费的IDEs和编辑器

    程序员编程利器:20款最好的免费的IDEs和编辑器 还没转眼明年可就大年三十了,忙的可真是晕头转了个向,看着亲朋好友们那让人欣羡的小肚腩,不禁感慨,岁月是一把猪饲料,绿了芭蕉,肥了那杨柳小蛮腰,可怜我 ...

  6. 编程之法:面试和算法心得(寻找最小的k个数)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入n个整数,输出其中最小的k个. 分析与解法 解法一 要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个 ...

  7. 编程之法:面试和算法心得(字符串包含java实现)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都 ...

  8. 编程之法:面试和算法心得(旋转字符串java实现)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b ...

  9. 作为一名程序员,在面试中如何展现你Python的coding能力?

    来源商业新知,原文标题:如何在一场面试中展现你对Python的coding能力? 如果你已经通过了招聘人员的电话面试,那么下面正是该展现你代码能力的时候了.无论是练习,作业,还是现场白板面试,这都是你 ...

随机推荐

  1. 深入解密.NET(Tuple元祖)

    元组(Tuple)数学概念上是指包含特定元素与数列的数据结构,n-Tuple称为一个n元祖.比如拿数据表来类比,数据表的每一行就是一个元祖,每一列是元祖的一个属性. 它可以视为由于你不想大动干戈创建一 ...

  2. Python使用suds调用webservice报错解决方法:AttributeError: 'Document' object has no attribute 'set'

    使用python的suds包调用webservice服务接口,报错:AttributeError: 'Document' object has no attribute 'set' 调用服务接口代码: ...

  3. StackExchange.Redis在net中使用

    redis 官网https://redis.io redis 下载  进入下载页面  https://redis.io/download https://github.com/MicrosoftArc ...

  4. @AfterThrowing

    @AfterThrowing(throwing="ex", pointcut="within(com.xms.controller.*)") public vo ...

  5. 删掉centos原有的openjdk并安装sun jdk

    [环境变量]删掉centos原有的openjdk并安装sun jdk   一.卸载原有openjdk rpm -qa | grep java 之后,将展示出来的全部卸载掉,我这里是5个 rpm -e ...

  6. SQLGetEnvAttr

    SQLGetEnvAttr 函数定义: 用于得到当前环境的各项设置属性 SQLRETURN SQLGetEnvAttr( SQLHENV     EnvironmentHandle, SQLINTEG ...

  7. html5-特殊符号的使用

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  8. DBUtils (30)

    DBUtils是java编程中的数据库操作实用工具,小巧简单实用. DBUtils封装了对JDBC的操作,简化了JDBC操作,可以少写代码. Dbutils三个核心功能介绍 一.  QueryRunn ...

  9. 20165215 2017-2018-2 《Java程序设计》第6周学习总结

    20165215 2017-2018-2 <Java程序设计>第6周学习总结 教材学习内容总结 chapter8 Java把String类定义为final类,即String类不能有子类 用 ...

  10. TestNG 搭建测试框架 自动化测试

    框架层级及基本组件:    参考:https://www.cnblogs.com/jier888/p/8998724.html Java作为开发语言 Maven管理项目及Jar包 Testng作为测试 ...