本文主要是介绍算法练习-右旋字符串(思路+流程图+代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
难度参考
难度:简单
分类:字符串
难度与分类由我所参与的培训课程提供,但需要注意的是,难度与分类仅供参考。以下内容均为个人笔记,旨在督促自己认真学习。
题目
字符串的【右旋转】操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串s和一个 正整数k,请编写一个函数,将字符串中的后面k个字符移到字符串的前面,实现字符串的【右旋转】操作。
示例:
输入:s="abcdefg",k=2
输出:"fgabcde"
解释:k=2,所以将字符串s尾的两个字符移动到字符串的开头
额外要求: 不能申请额外空间,只能在字符串s上操作。
思路
题目要求实现字符串的右旋转操作,即将字符串尾部的若干个字符移动到字符串的前面。同时,要求不能申请额外空间,只能在字符串上操作。
- 先整体反转整个字符串。
- 再分别反转前 k 个字符和剩余的字符。
详细步骤
- 使用一个辅助函数
reverseString
,该函数接收一个字符串和两个索引参数,将这两个索引之间的子串进行反转。 - 主函数
rotateString
中,首先计算实际需要旋转的步数k
(防止k
大于字符串长度),然后执行以下步骤:- 反转整个字符串。
- 反转前 k 个字符。
- 反转剩余的字符。
示例
输入:s="abcdefg", k=2
-
整体反转整个字符串:
- 反转前:"abcdefg"
- 反转后:"gfedcba"
-
反转前 k 个字符:
- 反转前 2 个字符:"fgedcba"
-
反转剩余的字符:
- 反转剩余的字符:"fgabcde"
最终的输出结果为:"fgabcde"
梳理
让我们仔细解释一下为什么这样的算法能够实现字符串的右旋转操作。
首先,整体思路涉及三个关键步骤,以实现字符串的右旋转。这三个步骤是相互关联的,确保最终结果正确。以下是对每个步骤的详细解释:
- 整体反转整个字符串: 这一步的目的是将字符串的尾部移到前面,实现了一部分右旋转。例如,"abcdefg" 反转后变为 "gfedcba"。
- 反转前 k 个字符: 接下来,反转字符串的前 k 个字符。这一步的目的是将之前移动到开头的尾部字符重新移到字符串的尾部。在上面的例子中,反转前 2 个字符后得到 "fgedcba"。
- 反转剩余的字符: 最后,反转剩余的字符。这一步确保整个字符串的顺序正确,实现了右旋转。在上面的例子中,反转剩余字符后得到最终结果 "fgabcde"。
具体的来说就是,
- 整体反转整个字符串实现了尾部字符移到前面的效果。
- 反转前 k 个字符确保之前移到前面的尾部字符重新回到了字符串的尾部。
- 反转剩余的字符则确保整个字符串的顺序正确,最终实现了右旋转的操作。
这样的操作保证了在不使用额外空间的情况下,通过原地操作字符串,实现了字符串的右旋转。这个算法的核心在于巧妙地利用字符串反转的特性,以及在合适的步骤中进行反转,最终得到期望的结果。
代码
#include <iostream>
#include <algorithm>using namespace std;// 反转字符串的子函数,反转字符串 s 中从索引 start 到索引 end 的部分
void reverseString(string& s, int start, int end) {while (start < end) {swap(s[start], s[end]); // 使用 swap 函数交换字符start++;end--;}
}// 右旋转字符串的主函数
void rotateString(string& s, int k) {int n = s.length();k = k % n; // 处理 k 大于字符串长度的情况,确保 k 在有效范围内// 步骤1:反转整个字符串reverseString(s, 0, n - 1);// 步骤2:反转前 k 个字符reverseString(s, 0, k - 1);// 步骤3:反转剩余的字符reverseString(s, k, n - 1);
}int main() {string s = "abcdefg";int k = 2;// 调用右旋转函数rotateString(s, k);// 输出结果cout << "输出:" << s << endl;return 0;
}
打卡
这篇关于算法练习-右旋字符串(思路+流程图+代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!