刷题08 位运算easy


67. 二进制求和

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。

输入:a = "11", b = "1"
输出:"100"
输入:a = "1010", b = "1011"
输出:"10101"
void reserve(char *s){
    int l=0,r=strlen(s)-1;
    while(l<r){
        char tmp=s[l];
        s[l]=s[r];
        s[r]=tmp;
        l++;r--;
    }
}
char* addBinary(char* a, char* b) {
    reserve(a);
    reserve(b);
    int l1=strlen(a),l2=strlen(b),l=0;
    int n=fmax(l1,l2);
    int carry=0;
    char* res=malloc(sizeof(char)*(2+n));
    for(int i=0;i<n;++i){
        if(i<l1&&a[i]=='1'){
            carry+=1;
        }
        if(i<l2&&b[i]=='1'){
            carry+=1;
        }
        res[l++]=carry%2+'0';
        carry/=2;
    }
    if(carry){
        res[l++]='1';
    }
    res[l]='\0';
    reserve(res);
    return res;
}


231. 2 的幂

 给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。

如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

输入:n = 16
输出:true
解释:24 = 16

        注意负数的情况,如果幂是偶数次方就返回false。注意循环的终止条件是n>1,若是n>0的话,最后都会返回false 

bool isPowerOfTwo(int n) {
    if(n==0) return false;
    bool flag=false;
    if(n<0) flag=true;
    int cnt=0;
    while(n>1){
        if(n%2==1) return false;
        n/=2;
        cnt++;
    }
    if(flag&&cnt%2==0) return false; 
    return true;
}


268. 丢失的数字

 给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。
int missingNumber(int* nums, int numsSize) {
    int flag[10002]={0};
    for(int i=0;i<numsSize;++i){
        flag[nums[i]]=1;
    }
    for(int i=0;i<numsSize;++i){
        if(flag[i]==0){
            return i;
        }
    }
    return numsSize;
}


338. 比特位计数  

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10
int fun(int n){
    int cnt=0;
    while(n){
        cnt+=n%2;
        n/=2;
    }
    return cnt;
}
int* countBits(int n, int* returnSize) {
    int *res=malloc(sizeof(int)*(n+1));
    int l=0;
    for(int i=0;i<=n;++i){
        int cur=fun(i);
        res[l++]=cur;
    }
    *returnSize=n+1;
    return res;
}


405. 数字转换为十六进制数

char* reverse(char* s){
    int n=strlen(s);
    int l=0,r=n-1;
    while(l<r){
        char tmp=s[l];
        s[l]=s[r];
        s[r]=tmp;
        l++;r--;
    }
    return s;
}
char * toHex(int num){
    if(num==0) return "0";
    if(num==-1) return "ffffffff";
    char* res=malloc(sizeof(char)*32);
    int l=0;
    unsigned int newnum=(unsigned int)num;
    while(newnum){
        int cur=newnum%16;;
        if(cur>=10){
            cur-=10;
            res[l++]=cur+'a';
        }else{
            res[l++]=cur+'0';
        }
        newnum/=16;
    }
    res[l]='\0';
    return reverse(res);
}

 
868. 二进制间距

给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 。如果不存在两个相邻的 1,返回 0 。

如果只有 0 将两个 1 分隔开(可能不存在 0 ),则认为这两个 1 彼此 相邻 。两个 1 之间的距离是它们的二进制表示中位置的绝对差。例如,"1001" 中的两个 1 的距离为 3 。

输入:n = 22
输出:2
解释:22 的二进制是 "10110" 。
在 22 的二进制表示中,有三个 1,组成两对相邻的 1 。
第一对相邻的 1 中,两个 1 之间的距离为 2 。
第二对相邻的 1 中,两个 1 之间的距离为 1 。
int binaryGap(int n) {
    int last=-1,ans=0;//last表示上一个1的下标
    int i=0;
    while(n){
        if(n%2==1){
            if(last!=-1){
                //若上一个1存在,更新ans的值
                ans=fmax(ans,i-last);
            }
            last=i;//将当前1的下标赋值给last
        }
        i++;
        n=n/2;
    }
    return ans;
}


1009. 十进制整数的反码

 每个非负整数 N 都有其二进制表示。例如, 5 可以被表示为二进制 "101"11 可以用二进制 "1011" 表示,依此类推。注意,除 N = 0 外,任何二进制表示中都不含前导零。

二进制的反码表示是将每个 1 改为 0 且每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"

输入:5
输出:2
解释:5 的二进制表示为 "101",其二进制反码为 "010",也就是十进制中的 2 。
int bitwiseComplement(int n) {
    if(n==0) return 1;
    int ans=0;
    int i=0;
    while(n){
        if(n%2==0){
            ans+=(1<<i);
        }
        i++;
        n/=2;
    }
    return ans;
}


1.04. 回文排列

给定一个字符串,编写一个函数判定其是否为某个回文串的排列之一。回文串是指正反两个方向都一样的单词或短语。排列是指字母的重新排列。回文串不一定是字典当中的单词。

输入:"tactcoa"
输出:true(排列有"tacocat"、"atcocta",等等)
bool canPermutePalindrome(char* s){
    int n=strlen(s);
    int flag[128]={0};//不一定是字母,故需128位
    for(int i=0;i<n;++i){
        flag[s[i]]++;
    }
    int isodd=false;//奇数个字符只能出现一次
    for(int i=0;i<128;++i){
        if(flag[i]%2==1){
            if(isodd){
                return false;
            }else{
                isodd=true;
            }
        }
    }
    return true;
}

  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值