Leetcode原题-数字的补数(不用位运算)

对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。

例如,整数 5 的二进制表示是 “101” ,取反后得到 “010” ,再转回十进制表示得到补数 2 。 给你一个整数 num ,输出它的补数。

示例 1:
输入:num = 5
输出:2
解释:5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。

示例 2:
输入:num = 1
输出:0
解释:1 的二进制表示为 1(没有前导零位),其补数为 0。所以你需要输出 0 。

首先,看到这么一个题目首先想到的肯定是位运算,但是在这里不用位运算求解.让我们换一种思路
有没有可能,把这一个数的二进制每位都存在一个数组里,然后让数组里的每一个元素一次取反,接着再把数组中的数取出转换为一个新的十进制数呢?
因此,思路如下:

  1. 创建存放数的二进制每一位的数组
  2. 将数组的每一位元素取反
  3. 取出数组,放到新数中

但是这里需要注意的是,因为数字是取余只能从后往前取的,而数组却是从前往后遍历的,所以,这里还需要一部操作,那就是逆序数组
因此,我们这里要实现三个函数分别为:

  1. 计算该数字二进制位数

计算位数其实很简单,如十进制让该数/10的操作,二进制只不过是/2罢了

int counttimes(int n)
{
    int len=0;
    while(n)
    {
        len++;
        n/=2;
    }

    return len;
}

2.逆序排列数组

逆序排列数组其实就是两个指针,一个指向开头,一个指向数组尾,直到两个指到了同一个元素再停止交换

在这里插入图片描述

void reverse(int* arr,int left,int right)
{
   while(left<right)
   {
       int temp=arr[left];
       arr[left]=arr[right];
       arr[right]=temp;

       left++;
       right--;
   }
}
  1. 反转数位

反转数位也很简单,直接遍历数组,选择判断即可

void reverse_Nums(int* arr,int len)
{
    for(int i=0;i<len;i++)
    {
        if(arr[i]==1)
        {
            arr[i]=0;
        }
        else
        {
            arr[i]=1;
        }
    }
}

最后还有一个需要注意的点就是将数组中的元素放入数组中也需要倒着取出元素
下面是完整代码

//计算该数字二进制位数
int counttimes(int n)
{
    int len=0;
    while(n)
    {
        len++;
        n/=2;
    }

    return len;
}

//逆序排列数字,因为数字放到数组里和数组下标是反的
void reverse(int* arr,int left,int right)
{
    while(left<right)
    {
        int temp=arr[left];
        arr[left]=arr[right];
        arr[right]=temp;

        left++;
        right--;
    }
}

//反转数位
void reverse_Nums(int* arr,int len)
{
    for(int i=0;i<len;i++)
    {
        if(arr[i]==1)
        {
            arr[i]=0;
        }
        else
        {
            arr[i]=1;
        }
    }
}

int findComplement(int num)
{
    int len=counttimes(num);//求出该数字二进制位数
    int arr[len];
    int res=0;//结果数字
    int arr_index=0;

    //将数字存放入数组
    while(num)
    {
        arr[arr_index++]=num%2;
        num/=2;
    }
    
    reverse(arr,0,len-1);//将数组中元素和数字二进制位对齐
    reverse_Nums(arr,len);


    //逆序取数
    for(int i=len-1,j=0;i>=0;i--)
    {
        res+=arr[i]*pow(2,j);
        j++;
    }

    return res;
}

这个题的思路是我目前能想到的最好的了,而且也比较好理解,根据现有知识也能掌握.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值