今天在牛客网上做了一道题,题意就是求左旋转字符串。我使用辗转相除法解之,一次性AC通过。实话说,每次写算法一次性通过,甚至一点编译错误都没有,我觉得这就是对我最好的嘉奖。

题目描述:

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

这么多废话,实际上就是求左旋转字符串。这里我先给出我的辗转相除法代码:

class Solution {
public:
string LeftRotateString(string str, int n) {
int length = str.length();
if(length <= n)
return str;
char *sz = new char[length+1];
strcpy(sz, str.c_str());
int times = gcd(length, n);
while(times--) //注意这里先判断,再--,所以下面times已经是减过了的
rotate(sz+times, length, n);
string res(sz);
delete []sz;
return res;
}
void rotate(char* sz, int length, int n){
char* p1 = sz;
char* p2 = sz + n;
char tmp = *sz;
while(p2 != sz){
*p1 = *p2;
p1 = p2;
if(p2 + n > sz + length - 1)
p2 = sz + (n - ((sz + length) - p2));
else
p2 += n;
}
*p1 = tmp;
}
int gcd(int m, int n){
while(n != 0){
if(m < n)
std::swap(m, n);
int tmp = m % n;
m = n;
n = tmp;
}
return m;
}
};

思路大致是这样的:对于一个字符串,先求出GCD,也就是字符串长度和要旋转个数的最大公约数。这个最大公约数是我们即将要用到的循环链的数目。也就是执行rotate循环的次数。

现在解释什么是循环链。比如“1234”,我们求它把前面3个字符放到后面的情况,即n=3。此时GCD(4,3)=1,即times=1。那么分析rotate函数。由于在该函数中我们用tmp保存了sz,你需要用tmp保存了这个值,也就是p1的值,我们就可以使用*p2覆盖该位置的值了,并且p2=p1+n。对于该情况,rotate函数依照代码执行的流程为(用下划线表示空位,也就是p1指向的将被覆盖的位置):

_ 2 3 4 -> 4 2 3 _ -> 4 2 _ 3 -> 4 _ 2 3 -> 4 1 2 3(这是最后一步:*p1=tmp)

如上,这个rotate函数只需执行一次就可以达到目的,旋转3个字符要求达成。这就叫做一次循环链,最大公约数times的值就说明了这个问题。

再举一例,有两个循环链的例子:还是“1234”,求把前两个字符放在后面的情况,即n=2。GCD(4,2)=2,可知有两个循环链。我们来验证一下:

第一次:times=1(由于times--),所以p1=2,p2=4(p2=p1+n),所以循环流程:

1 _ 3 4 -> 1 4 3 _ -> 1 4 3 2

第二次:times=0,并且p1=1,p2=3,循环流程为:

_ 4 3 2 -> 3 4 _ 2 -> 3 4 1 2

没错,循环两次就成功解决问题了,所以最大公约数就是循环链的数目,也就是执行rotate函数的次数。

我在牛课网上看了,大多数人可能使用没有改变内存的substr,有的人使用三次reverse,没有见到有人使用GCD。我之前也用reverse,但是现在熟悉了新技能,那就用它吧。

对了,我的思路是以前剖析STL源代码学习的,如果感兴趣可以看STL rotate函数的实现,对不同迭代器重载不同的版本,其中RandomIterator版本使用的就是GCD。

辗转相除法(GCD)求左旋转字符串的更多相关文章

  1. 剑指Offer面试题:34.翻转单词顺序VS左旋转字符串

    一.题目一:翻转单词顺序 1.1 题目说明 题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a st ...

  2. 【面试题042】翻转单词顺序VS左旋转字符串

    [面试题042]翻转单词顺序VS左旋转字符串 题目一:     输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.     例如输入字符串“I a ...

  3. 九度OJ 1362 左旋转字符串(Move!Move!!Move!!!)【算法】

    题目地址:http://ac.jobdu.com/problem.php?pid=1362 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运 ...

  4. 《剑指offer》第五十八题(左旋转字符串)

    // 面试题58(二):左旋转字符串 // 题目:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部. // 请定义一个函数实现字符串左旋转操作的功能.比如输入字符串"abcde ...

  5. 编程算法 - 左旋转字符串 代码(C)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/37689725 左旋转字符串 代码(C) 本文 ...

  6. 剑指offer-第六章面试中的各项能力(翻转单词的顺序VS左旋转字符串)

    //题目1:翻转单词顺序例如“Hello world!”翻转后为world! Hello. //思路:首先翻转整个字符串,然后再分别翻转每个单词. //题目2:左旋转字符串,是将字符串的前面几个(n) ...

  7. 剑指Offer - 九度1362 - 左旋转字符串(Move!Move!!Move!!!)

    剑指Offer - 九度1362 - 左旋转字符串(Move!Move!!Move!!!)2013-11-23 03:05 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任 ...

  8. 笔试算法题(13):反转链表 & 左旋转字符串

    出题:反转链表(递归和非递归解法): 分析:有递归跟非递归实现,注意对原始链表头节点的处理,因为其他节点都指向下一个节点,其需要指向NULL: 解题: struct Node { int v; Nod ...

  9. 题目1362:左旋转字符串(Move!Move!!Move!!!)

    题目1362:左旋转字符串(Move!Move!!Move!!!) 时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:2306 解决:961 题目描述: 汇编语言中有一种移位指令叫做循环左移( ...

随机推荐

  1. java为什么要重写hashCode和equals方法?

    如果不被重写(原生)的hashCode和equals是什么样的? 不被重写(原生)的hashCode值是根据内存地址换算出来的一个值. 不被重写(原生)的equals方法是严格判断一个对象是否相等的方 ...

  2. 【新特性】JDK1.7

    一.switch中可以使用字串 String s = "test";switch (s) { case "test" :   System.out.printl ...

  3. .NET Core到底有多强?

    测试代码: C# Release 未优化 class Program { static long counter = 0; static void Main(string[] args) { for ...

  4. Linear Regression with machine learning methods

    Ha, it's English time, let's spend a few minutes to learn a simple machine learning example in a sim ...

  5. hbase调优配置项笔记

    gc配置 hbase-env.sh export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC" export HBASE_OPT ...

  6. 「Python」数据清洗常用正则

    对爬虫数据进行自然语言清洗时用到的一些正则表达式 标签中的所有属性匹配(排除src,href等指定参数) 参考链接 # \b(?!src|href)\w+=[\'\"].*?[\'\&quo ...

  7. linux查看用户登录时间以及命令历史

    1.查看当前登录用户信息 who命令: who缺省输出包括用户名.终端类型.登陆日期以及远程主机. who /var/log/wtmp 可以查看自从wtmp文件创建以来的每一次登陆情况 (1)-b:查 ...

  8. postman(十):配置jenkins自动发送邮件(邮件包含测试报告)

    继续说一下jenkins与postman的集成 上一篇通过jenkins远程执行postman导出的脚本,并把html报告指定输出到了jenkins对应的job工作空间,接下来配置一下当jenkins ...

  9. 主成分分析(PCA)原理及R语言实现 | dimension reduction降维

    如果你的职业定位是数据分析师/计算生物学家,那么不懂PCA.t-SNE的原理就说不过去了吧.跑通软件没什么了不起的,网上那么多教程,copy一下就会.关键是要懂其数学原理,理解算法的假设,适合解决什么 ...

  10. JSP+MySQL最简单的登录和注册的实现 --Java Web温习

    一.开发环境 开发工具:eclipse 2018-09 操作系统:win10 二.实现 1.目录结构: 2.数据库(创建tmp数据库,新建user表,user表结构如下) 3.功能简介 功能比较简单, ...