所有长度为n的二进制的字符串_算法题——[leetcode1611]把n变为0的最少操作数

Hard级别的新题:给定非负整数n,你可以使用两种操作, 把它变为0。两种操作是:
(1)变换最低二进制位。

(2)变换非最低二进制位,比它更低的位必须是1000000....。

求最少操作次数。

数据范围0<=n<=1000000000。

例如输入n = 0,返回0。

再如输入n = 3,返回2。因为要11->01->10

分析:比较难的题,其实是格雷码,但要仔细分析……用几个例子试一下2的幂 (用二进制表示)

1->0  1步

10->11->01->00  3步

100->101->111->110->010->011->001->000  7步

从2 ^ m变为0,需要2 ^ (m + 1) - 1步——即上面每条链包含2 ^ (m + 1)个数。

来看一下如何构造:

按最高位分成两段 ,最高位为1是前半段,低位是上一条链倒置, 最高位为0的是后半段, 低位完全是上一条链。

例如100开始的链

前半段是1(00)->1(01)->1(11)->1(10)

括号里的部分恰好是上一条链10->11->01->00倒过来 (其实从x变成0和从0变成x步数一样)。

后半段是0(10)->0(11)->0(01)->0(00)

括号里的部分正好就是上一条链10->11->01->00。

于是给定任意n > 0, 我们用二进制表示它为(1x), 我们希望找到(1x)在哪条链里, 这个容易,就是n的bti数m, 这条链的第一个数是2 ^ (m - 1),这条链的长度是2 ^ m - 1。然后我们想看一下(1x)在这条链的什么位置,显然它在这条链的前半段,因为开头是1。那相当于看x在它所在链到0的距离——因为前半段是倒置的。所以问题转换为,求(2 ^ m - 1)减去x变为0(或者说0变为x)的距离。递归地调用f(x)即可。

代码:

class Solution {public:    int minimumOneBitOperations(int n) {        if (n == 0) return 0;        int m = 1;        for (; m <= n; m <<= 1)        ;        return m - 1 - minimumOneBitOperations((m >> 1) ^ n);            }};
精彩推荐

算法题——[leetcode1553]吃完n个橘子的最少天数

算法题——[leetcode1011]把所有包裹在D天内送完的最小容量

算法题——[leetcode1540]在k步内变换字符串

算法题——[leetcode1545]第n个二进制串的第k位

81a6e459173443c31d670d2c5905e6fe.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值