LintCode Ladder4 - Math$Bit Manipulation
1、Flip Bits
题目:给你两个数字A和B,问你需要改变A的二进制位的几个位使其变成B。
Example:
A = 31(11111)
B = 14(01110)
return 2;
只需要修改第一位和第5个二进制位即可。分析:
从题目的意思,我们可以直接比较所有对应的二进制位,因为A和B都是32位的整数。我们可以直接比较所有的32位,记录不同的位置的个数即可。
继续想,既然是相同的位置对赢得0-1不同,那不就是异或操作了吗,于是我们可以领 C = A ^ B.计算C的1的个数就是最终的结果。
Code:
class Solution {
public:
/**
*@param a, b: Two integer
*return: An integer
*/
int bitSwapRequired(int a, int b) {
// write your code here
int cnt = 0, x = a ^ b;
for(int i = 0;i < 32;i++){
cnt += ((x & (1 << i)) != 0);
}
return cnt ;
}
};
2、O(1) Check Power of 2
题目:使用O(1)的时间,判断一个数n是不是2的幂次方。
Example:
n = 4, return true;
n = 5, return false;分析:
1、如果是一个数n = 2 ^ i.只需要对这个n判断是否能够被2除,到达1。如果可以达到1就return true;else return false。
2、但是题目要求是O(1)的操作,上面的解法显然不是O(1)的操作,而是O(logn)。分析一个一个数n如果可以表示成
n = 2 ^ i, (i>=0)。
n = (1000..000) 首先1个1,接着i个0。
n-1 = (0111..111) 首先1个0,接着i个1.
而且有 n & (n-1) = 0。
于是得到计算公式,n满足上式的都是2的幂次方。
Code:
class Solution {
public:
/*
* @param n: An integer
* @return: True or false
*/
bool checkPowerOf2(int n) {
// write your code here
if(n<=0) return 0;
return (n&(n-1))==0;
}
};
3、Trailing Zeros
题目:给你一个数n,计算n!的末尾的0的个数。
Example:
11! = 39916800, so should return 2.分析:
对于这个题,我们可以想到一个知识,怎么才能在末尾出现0,一个数k * 10会在末尾出现一个0,又因为10可以分解素因子10 = 2 * 5。于是我们只需要知道n! 中素因子分解后,2的个数count(2)和5的个数count(5)的最小值即可。answer = min(count(2), count(5))。
1、根据素因子分解的原理,count(2)>=count(5).
2、计算出count(5)的个数。
3、根据 Legendre’s formula
vp(n!)=∑∞1npi 链接
Code:
class Solution {
public:
// param n : description of n
// return: description of return
long long trailingZeros(long long n) {
long long cnt = 0;
while(n){
cnt += n / 5;
n /= 5;
}
return cnt;
}
};
4、Update Bits
题目描述:给出两个32位的整数N和M,以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M(M会是N中从第i为开始到第j位的子串)
Example:
给出N = (10000000000)2,
M = (10101)2, i = 2, j = 6
返回 N = (10001010100)2分析:
我们可以直接想到,让N减去[i-j]对应位的值,再加上M左移i位的值,就是替换之后的值。
1、将N转化为二进制,计算[i-j]对应的位的值t,(n-t)+(m<
class Solution {
public:
/**
*@param n, m: Two integer
*@param i, j: Two bit positions
*return: An integer
* 将n分成三段 a[0-i) b[i-j] c(j-N]
* 掩码的问题,需要仔细考虑
*/
int updateBits(int n, int m, int i, int j) {
// write your code here
int mask;
if(j<31){
mask=~((1<<(j+1))-(1<<i));
}else{
mask=(1<<i)-1;
}
return (m<<i)+(n&mask);
}
};
5、Unique Binary Search Trees
题目:给出 n,问由 1…n 为节点组成的不同的二叉查找树有多少种?
分析:这是有公式的题目,问题是能不能记住这个公式。
h(n)=(4∗i−2)∗h(n−1)n+1
h(1)=1
Code:
class Solution {
public:
/**
* @paramn n: An integer
* @return: An integer
* catalan Number
* h(n)=((4*n-2)/(n+1))*h(n-1);
*/
int numTrees(int n) {
// write your code here
if(n==0) return 1;
long long h = 1; //防止数值上溢
for(int i=2;i<=n;i++){
h = ((4*i-2)*h/(i+1));
}
return h;
}
};
6、Fast Power
题目:计算 an%b 的值,其中a,b和n都是32位的整数。
分析:
经典的二分快速幂,
a^n%b == a^(n/2)%b * a^(n/2)%b; n%2==0;
a^n%b == a^(n/2)%b * a^(n/2)%b * a%b; n%2==1;
Code:
class Solution {
public:
/*
* @param a, b, n: 32bit integers
* @return: An integer
*/
int fastPower(int a,int b,int n){//bud
if(n==0) return 1%b;
long long ans=1;
long long x=a;
while(n){
if(n&1) ans=ans*(x%b)%b;
x=((x%b)*(x%b))%b;
n=n>>1;
}
return ans;
}
int fastPower1(int a,int b,int n){//递归形式,当然也有迭代形式
long long ans=1;
if(n==0) return 1%b;
if(n==1) return a%b;
long long x=fastPower(a,b,n>>1);//注意中间精度溢出
ans=((x%b)*(x%b))%b;
if(n&1){//n=2*k+1
ans=(ans*(a%b))%b;
}
return ans;
}
};
7、Binary Representation
题目:给定一个数将其转换为二进制(均用字符串表示),如果这个数的小数部分不能在 32 个字符之内来精确地表示,则返回 “ERROR”。
Example:
n = “3.72”, 返回 “ERROR”.
n = “3.5”, 返回 “11.1”.分析:这个题其实很简单,就是模拟的时候需要注意一些问题。
1、找到小数点,分成两部分处理,整数和小数。
2、小数部分是每次乘以2
3、整数部分是除以2.
4、注意小数的不能满足的情况。
Code:
class Solution {
public:
/**
*@param n: Given a decimal number that is passed in as a string
*@return: A string
*/
string Int2Binanry(string n){
string s = "";
int t = 0;
for(int i=0;i<n.size();i++){
t = t*10 + (n[i] - '0');
}
if(t==0) s="0";
while(t){
s += char(t%2 + '0');
t /= 2;
}
reverse(s.begin(),s.end());
return s;
}
//处理小数部分
string DecBinary(string n){
string s = "";
long long t = 0; // long long 防止乘法越界上溢
for(int i=0;i<n.size();i++){
t = t*10 + (n[i] - '0');
}
int k = 0;
long long m = (long long)pow(10,n.size());
//cout<<t<<" "<<m<<endl;
while(k<32){
s += (t*2 / m) + '0';
t = t * 2 % m;
if(t==0) break;
k ++;
}
if(k >= 32) s = "2";
return s;
}
string binaryRepresentation(string n) {
// wirte your code here
if(find(n.begin(), n.end(), '.') == n.end()) n += '.';
//cout<<n<<endl;
string::iterator it = find(n.begin(), n.end(), '.');
string f(n.begin(),it);
string d(it+1,n.end());
//cout<<f<<endl;
//cout<<d<<endl;
string fs = Int2Binanry(f);
string ds = Dec2Binary(d);
if(ds == "2") return "ERROR";
if(ds=="" || ds=="0") return fs;
return fs+'.'+ds;
}
};
ps: 欢迎批评指正,喵~