题意整理:
题目给出一个表示二进制数的字符串,要求输出将字符串循环右移k位后得到新的二进制串对应的二进制数的的十进制值。
方法一:剪切得到右移后字符串求值
核心思想:
将一个字符串循环右移k位,实际上就是将其末尾的k个字符剪切后拼接至首部,所以可以剪切后进行按位计算即可
例如:(为方便观察,此处不以二进制串为例而是以十进制串为例)
核心代码:
class Solution { public: long long rotateRight(string str, int k) { int n = str.length(); //剪切 string res = str.substr(0, n - k); str = str.substr(n - k, k) + res; long long ans = 0; //统计答案 for(int i = 0; i < n; ++i) { ans = ans * 2 + (str[i] - '0'); } return ans; } };
复杂度分析:
时间复杂度:。既for循环的开销
空间复杂度:,既剪切使用的中间字符串的开销
方法二:通过反转实现剪切
核心思想:
实际上,也有不使用额外字符串对字符串进行循环移位工作的方法。先将整个字符串反转,后分别对前半部的长度为的字符串进行反转以及后半部的长度为的字符串进行反转即可
核心代码:
class Solution { public: long long rotateRight(string str, int k) { //三次反转实现移动k位 reverse(str.begin(), str.end()); reverse(str.begin(), str.begin() + k); reverse(str.begin() + k, str.end()); long long ans = 0; //统计答案 for(int i = 0; i < str.length(); ++i) { ans = ans * 2 + (str[i] - '0'); } return ans; } };
复杂度分析:
时间复杂度:,反转字符串开销为,按位计算开销为,故总开销为
空间复杂度:,只使用了常数个变量
方法三:计算中移位
核心思想:
也可以不显式的计算出移位后的字符串,而是在按位累加的过程中进行移位即可,需要注意超过边界的问题。
对于字符串位于位置的元素1,其原本大小为,而右移位后大小为,而由于该数值可能小于0,这时既为循环位移至左侧,故需要加上字符串长度,故最终表示右移位后大小使用为
核心代码:
class Solution { public: long long rotateRight(string str, int k) { int n = str.length(); long long ans = 0; //统计答案 for(int i = 0; i < n; ++i) { if(str[i] == '1') { //直接移位处理 ans += 1ll << ((2 * n - 1 - i - k) % n); } } return ans; } };
复杂度分析:
时间复杂度:。既for循环开销
空间复杂度:,只使用了常数个变量