题解 | #循环右移#

循环右移

http://www.nowcoder.com/practice/1d461107631246e693bda9a4f9cc50b8

题意

以字符串的形式给一个二进制数,对这个二进制数循环右移kkk位,求右移结果的十进制的值。

二进制位数小于等于636363

方法

模拟

按照题意,我们操作字符串k次,每次移动一位,63次后得到了目标的二进制表示的字符串

再对二进制字符串进行转化成10进制,需要注意的是这里是long long 不是int

代码

class Solution {
public:
    /**
     * 位移后二进制串的十进制值
     * @param str string字符串 二进制字符串
     * @param k int整型 循环位移次数
     * @return long长整型
     */
    long long rotateRight(string str, int k) {
        for(int i = 0;i<k;i++){
            char ch = str[str.length()-1];
            str = ch+str;
            str.pop_back();
        }
        long long res = 0;
        for(int i = 0;i<str.length();i++){
            res*=2;
            res+= str[i]-'0';
        }
        return res;
    }
};

复杂度分析

时间复杂度:

我们首先操作字符串k次, 每次将字符串最后一位移动到最前,时间复杂度为 O(k)O(k)O(k)

然后是进制转换,对每一位进行操作一次所以复杂度是O(len(str))O(len(str))O(len(str)),综上 总时间时间复杂度为O(k+len(str))O(k+len(str))O(k+len(str))

空间复杂度: 只用了常数大小的额外空间来记录结果和做for循环,所以空间复杂度为O(1)O(1)O(1)

抽象优化

如果我们需要算111nnn的和,我们并不需要循环从111nnn,而是可以直接求和公式,同样,虽然说题目描述是循环右移,那么可以看一下当前位置与实际位置的区别,从意义上完成一个等效的操作,而不去实际操作它

以样例数据为例

- 1 0 1 1 0
实际位置 2 3 4 0 1
当前位置 0 1 2 3 4
当前位置 2-2 3-2 4-2 5+0-2 5+1-2
实际位置 当前位置
i(i>=k)i(i>=k)i(i>=k) iki-kik
i(i<k)i(i<k)i(i<k) len(str)+iklen(str)+i-klen(str)+ik

这样的位置可以用取模汇总成一个表达式

实际位置 当前位置
iii (len(str)+ik)<mtext> </mtext>mod<mtext> </mtext>len(str)(len(str)+i-k)\bmod len(str)(len(str)+ik)modlen(str)

f(i)=(len(str)+ik)<mtext> </mtext>mod<mtext> </mtext>len(str)f(i)= (len(str)+i-k)\bmod len(str)f(i)=(len(str)+ik)modlen(str), f()=f(实际位置)=当前位置f()=

因此原来的进制转换是s[0 ~ len(str)-1],现在变成s[f(0) ~ f(len(str)-1)]

代码

class Solution {
public:
    /**
     * 位移后二进制串的十进制值
     * @param str string字符串 二进制字符串
     * @param k int整型 循环位移次数
     * @return long长整型
     */
    long long rotateRight(string str, int k) {
        long long res = 0;
        for(int i = 0;i<str.length();i++){
            res*=2;
            res+= str[((int)str.length()-k+i)%str.length()]-'0';
        }
        return res;
    }
};

复杂度分析

时间复杂度: 我们省去了字符串的操作步骤,直接转换,每一位一次运算,以时间复杂度是O(len(str))O(len(str))O(len(str))

空间复杂度: 只用了常数大小的额外空间来记录结果和做for循环,所以空间复杂度为O(1)O(1)O(1)

全部评论

相关推荐

10-07 23:57
已编辑
电子科技大学 Java
八街九陌:博士?客户端?开发?啊?
点赞 评论 收藏
分享
无情咸鱼王的秋招日记之薛定谔的Offer:好拒信,偷了,希望有机会用到
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务