辗转相除法(GCD)求左旋转字符串
今天在牛客网上做了一道题,题意就是求左旋转字符串。我使用辗转相除法解之,一次性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)求左旋转字符串的更多相关文章
- 剑指Offer面试题:34.翻转单词顺序VS左旋转字符串
一.题目一:翻转单词顺序 1.1 题目说明 题目一:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理.例如输入字符串"I am a st ...
- 【面试题042】翻转单词顺序VS左旋转字符串
[面试题042]翻转单词顺序VS左旋转字符串 题目一: 输入一个英文句子,反转句子中单词的顺序,但单词内字符的顺序不变.为简单起见,标点符号和普通字母一样处理. 例如输入字符串“I a ...
- 九度OJ 1362 左旋转字符串(Move!Move!!Move!!!)【算法】
题目地址:http://ac.jobdu.com/problem.php?pid=1362 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运 ...
- 《剑指offer》第五十八题(左旋转字符串)
// 面试题58(二):左旋转字符串 // 题目:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部. // 请定义一个函数实现字符串左旋转操作的功能.比如输入字符串"abcde ...
- 编程算法 - 左旋转字符串 代码(C)
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/37689725 左旋转字符串 代码(C) 本文 ...
- 剑指offer-第六章面试中的各项能力(翻转单词的顺序VS左旋转字符串)
//题目1:翻转单词顺序例如“Hello world!”翻转后为world! Hello. //思路:首先翻转整个字符串,然后再分别翻转每个单词. //题目2:左旋转字符串,是将字符串的前面几个(n) ...
- 剑指Offer - 九度1362 - 左旋转字符串(Move!Move!!Move!!!)
剑指Offer - 九度1362 - 左旋转字符串(Move!Move!!Move!!!)2013-11-23 03:05 题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任 ...
- 笔试算法题(13):反转链表 & 左旋转字符串
出题:反转链表(递归和非递归解法): 分析:有递归跟非递归实现,注意对原始链表头节点的处理,因为其他节点都指向下一个节点,其需要指向NULL: 解题: struct Node { int v; Nod ...
- 题目1362:左旋转字符串(Move!Move!!Move!!!)
题目1362:左旋转字符串(Move!Move!!Move!!!) 时间限制:2 秒 内存限制:32 兆 特殊判题:否 提交:2306 解决:961 题目描述: 汇编语言中有一种移位指令叫做循环左移( ...
随机推荐
- 关于文件目录等的特殊权限setuid, setgid , sticky chattr, lsattr
有三种特殊权限 总之, 设置这些特殊权限有两种方法, 一是使用 chmod ugo的方式, 另一个是 使用 数字的方式, 通常的读写执行 权限 是 3位 数字, 那么 特殊权限 就用 4位数字, 而且 ...
- 牛客练习赛43F Tachibana Kanade Loves Game
题目地址 Link 题解 这题其实就是求1~n中有多少与2~20互质的数,然后其实只跟1~20里面的质数有关. 那么考虑容斥一下求出来一共有多少个不互质的,用n减一下就是互质的数的个数了.然后判一下a ...
- [CodeForce 450A] Jzzhu and Children
题目链接:http://codeforces.com/problemset/problem/450/A /* * 计算一个人要是拿足够离开需要排多少次队,选排的次数多的那个人,如果两个人排的次数相同, ...
- 快速签发 Let's Encrypt 证书指南
本文仅记录给自己的网站添加"小绿锁"的动手操作过程,不涉及 HTTPS 工作原理等内容的讲解,感兴趣的同学可以参考篇尾的文章自行了解. 简单了解下我的实验环境: 云服务器:Cent ...
- Spring之bean的生命周期
这篇博文是spring生命周期的详解,目前限于作者自身的水平对于一些内容可能只知其然不知其所以然,所以博文中如果出现错误欢迎各位指出,同时我也会逐步提升自己的水平,争取能够多发布一些能让大家获益的博文 ...
- 承接微信小程序外包 H5外包就找北京动点软件开发团队
承接小程序外包 微信小程序外包 H5外包 就找北京动点软件 长年承接微信小程序.微信公众号开发 全职的H5开发团队,开发过几十款微信小程序公众号案例 欢迎来电咨询,索取案例! QQ:372900288 ...
- 自身使用的springboot项目中比较全的pom.xml
在学习的时候常建新的项目,mark下商用的jar <dependency> <groupId>org.mybatis</groupId> <artifactI ...
- [redis] redis 命令
- java,优先队列的用法
像C++语言一样,java中,也有包装好的优先队列类PriorityQueue. 用法如下(模板代码): 工作安排问题: 问题描述:设有n件工作分配给n个人,将工作i分配给第j个人所需的费用为cij. ...
- og协议-有利于SNS网站分享
一丶前言 全球快递toWhere官网发现使用og协议,并且支付宝和淘宝活动源码也会添加og协议,查阅资料弄清og协议是什么,此刻附上og协议官方文档 一丶什么是og协议 Open Graph通讯协定( ...