LintCode-更新二进制位

给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串)

样例

给出N = (10000000000)2,M = (10101)2, i = 2, j = 6

返回 N = (10001010100)2

挑战

最少的操作次数是多少?

分析:这道题粗粗一看蛮简单,但实际上坑很多,而且间接性的考了原码反码和补码(负数的二进制表示),我的做法是先都转换成二进制表示,然后再把二进制表示转成结果。

代码:

vector<int> toBinary(int n)
{
    bool positive = (n>=0);
    long long temp = positive?(long long)n:(long long)n*(long long)(-1);
    vector<int> A;
    while(temp>0)
    {
        A.push_back(temp&1);
        temp>>=1;
    }
    while(A.size()<32)
        A.push_back(0);
    if(A.size()>32)//负数极限
        A.pop_back();
    reverse(A.begin(),A.end());
    if(!positive)
    {
        for(int i=0;i<32;i++)
            A[i] = 1-A[i];
        int k = 31;
        while(k>=0&&A[k]!=0)
            k--;
        A[k++]=1;
        while(k<32)
            A[k++]=0;
    }
    return A;
}
int binaryToInt(vector<int> A)
{
    if(A[0]==1)
    {
        for(int i=1;i<32;i++)
            A[i] = 1-A[i];
        int k = 31;
        while(k>=0&&A[k]==1)
            k--;
        A[k++] = 1;
        while(k<32)
            A[k++] = 0;

    }
    long long ret = 0;
    for(int i=1;i<32;i++)
        ret = ret*2+A[i];
    return A[0]==0?ret:ret*-1;
}
class Solution {
public:
    /**
     *@param n, m: Two integer
     *@param i, j: Two bit positions
     *return: An integer
     */
    int updateBits(int n, int m, int i, int j) {
        // write your code here
        vector<int> A = toBinary(n);
        vector<int> B = toBinary(m);
        int len = j-i+1;
        int t = A.size()-1-i;
        int p = B.size()-1;
        while(len--)
        {
            A[t--] = B[p--];
        }
        int ret = binaryToInt(A);
        return ret;

    }
};
时间: 2024-11-03 05:38:33

LintCode-更新二进制位的相关文章

更新二进制位

该题的思路是首先把 int 对应的二进制形式转为 string(主要是 int 难以操作具体的位,转换为 string 形之后操作具体的位就简单多了)然后把 string 再转回 int 返回即可. int updateBits(int n, int m, int i, int j) { // write your code here string sn, sm; int flag = 0x01; int time = sizeof(int) * 8; //int 转 string while(

2017校招常考算法题归纳&amp;典型题目汇总

2017校招即将来临,我们为大家整理了2017校招的常考算法类型,以及对应的典型题目. 另附参考答案地址:http://www.jiuzhang.com/solution/ 数学 尾部的零 斐波纳契数列 x的平方根 x的平方根 2 大整数乘法 骰子求和 最多有多少个点在一条直线上 超级丑数 比特位操作 将整数A转换为B 更新二进制位 二进制表示 O(1)时间检测2的幂次 二进制中有多少个1 动态规划 编辑距离 正则表达式匹配 交叉字符串 乘积最大子序列 二叉树中的最大路径和 不同的路径 通配符匹

校招的常考算法类型以及对应的典型题目

数学 尾部的零斐波纳契数列x的平方根x的平方根2大整数乘法骰子求和最多有多少个点在一条直线上超级丑数 比特位操作 将整数A转换为B更新二进制位二进制表示O(1)时间检测2的幂次二进制中有多少个1 动态规划 编辑距离正则表达式匹配交叉字符串乘积最大子序列二叉树中的最大路径和不同的路径通配符匹配 堆 滑动窗口的中位数数据流中位数最高频的K个单词接雨水堆化排序矩阵中的从小到大第k个数 二叉树 二叉树中序遍历二叉树的序列化和反序列化子树最近公共祖先二叉树的层次遍历将二叉树拆成链表在二叉查找树中插入节点

[lintcode the-smallest-difference]最小差(python)

题目链接:http://www.lintcode.com/zh-cn/problem/the-smallest-difference/ 给定两个整数数组(第一个是数组 A,第二个是数组 B),在数组 A 中取 A[i],数组 B 中取 B[j],A[i] 和 B[j]两者的差越小越好(|A[i] - B[j]|).返回最小差. 排好序后用两个指针分别扫描两个数组,每次更新他们的差值的绝对值.并且依据他们两个数字的大小来决定谁来移动指针. 1 class Solution: 2 # @param

[LintCode/LeetCode]——两数和、三数和、四数和

LintCode有大部分题目来自LeetCode,但LeetCode比较卡,下面以LintCode为平台,简单介绍我AC的几个题目,并由此引出一些算法基础. 1)两数之和(two-sum) 题目编号:56,链接:http://www.lintcode.com/zh-cn/problem/two-sum/ 题目描述: 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 1

[LintCode] Trapping Rain Water II

Trapping Rain Water II Given n x m non-negative integers representing an elevation map 2d where the area of each cell is 1 x 1, compute how much water it is able to trap after raining. Example Given 5*4 matrix [12,13,0,12] [13,4,13,12] [13,8,10,12] [

Lintcode - Maximum Subarray III

Given an array of integers and a number k, find k non-overlappingsubarrays which have the largest sum. The number in each subarray should be contiguous. Return the largest sum. http://www.lintcode.com/en/problem/maximum-subarray-iii/ Thought: 一开始以为这和

LintCode : Inorder Successor in Binary Search Tree

Very interesting problem! http://www.lintcode.com/zh-cn/problem/inorder-successor-in-binary-search-tree/ Description: Given a binary search tree (See Definition) and a node in it, find the in-order successor of that node in the BST. Example: Given tr

topcoder-srm701-div2-900 博弈\计算二进制位1的个数\dp\状态压缩

借用一下qls翻译过来的题面 现在有 n 个石子,A 和 B 轮流取石子,A先,每次最多可以取 m 个石子,取到最后一个石子的人获胜,但是某个人如果取完石子时候剩余石子数的二进制表示中有奇数个1,这个人就输了给定 n 和 m,问谁赢n<=5e8, m<=50TL 2s 以前我是从来没接触过博弈的 首先普及一下博弈的基本知识.. 必胜态,必败态,以及必胜点与必败点 首先有一个字必须要看清楚,那就是"必"字 是必胜而不是,胜利就行,这个字很关键 如图所示,一个点是p-posit

C语言中一些乱七八糟的用法与细节(不断更新)

用C语言比较多,这篇是平时攒下的.有些内容在工作后可能会很常见,但是不用容易忘,所以就写篇博客吧. 一.printf的用法 %*可以用来跳过字符,可以用于未知缩进.像下面一样. for(i = 1; i < 10; i++) { printf("%*c\r%*c\n",  9 - abs(i - 5), '*', abs(i - 5) + 1, '*'); } %[]可以用来读取指定的内容,%[^]可以用来忽略指定内容(正则表达式?) %m可以不带参数,输出产生的错误信息 二.关