这是悦乐书的第240次更新,第253篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第107题(顺位题号是476)。给定正整数,输出其补码数。补充策略是翻转其二进制表示的位。例如:

输入:5

输出:2

说明:5的二进制表示为101(无前导零位),其补码为010,因此需要输出2。

输入:1

输出:0

说明:1的二进制表示形式为1(无前导零位),其补码为0,因此需要输出0。

注意:

  • 保证给定的整数适合32位有符号整数的范围。

  • 您可以假设整数的二进制表示中没有前导零位。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

先将正整数转为二进制字符串,然后变成字符数组,将其中的0变成1,1变成0,再将字符数组变为字符串,最后将字符串转为二进制数。

public int findComplement(int num) {
String str = Integer.toBinaryString(num);
char[] arr = str.toCharArray();
for (int i=0; i<arr.length; i++) {
if (arr[i] == '0') {
arr[i] = '1';
} else {
arr[i] = '0';
}
}
return Integer.parseInt(String.valueOf(arr), 2);
}

03 第二种解法

我们可以仔细观察题目所给的示例:

5表示的二进制数为101,最后的结果是2,所表示的二进制数为10,如果我们将其前导0补齐,就会发现101通过计算后要得到010,那么需要借助怎样的计算呢?

借助位运算,101^111 = 010,我们使用二进制数111和101做异或运算就可以得到最后的结果。

因此,我们需要获取num表示的二进制数长度,来组成一个由1组成新二进制数(长度和num表示的二进制数一致),再将两数做异或运算即可。

异或运算的规则是两边的对应位不同时,取1,否则取0。

public int findComplement2(int num) {
String str = Integer.toBinaryString(num);
String str2 = "";
for (int i=0; i<str.length(); i++) {
str2 += "1";
}
int res = Integer.parseInt(str2, 2);
return num^res;
}

04 第三种解法

还是第二种解法的思路,只不过将字符串操作换为了位运算操作,我们先将num右移,计算其二进制数有多少位,记为i,然后再对1进行左移i位,移完后得到的二进制数是1个1加上i个0,而不是i个1,所以我们需要减去1使其变成i个1,最后和num做异或运算并返回其结果。

public int findComplement3(int num) {
if (num == 0) {
return 1;
}
int i = 0;
while ((num>>i) != 0) {
i++;
}
int res = (1<<i)-1;
return num^res;
}

05 第四种解法

还是第二种解法的思路,与第三种解法的位运算不同,借助包装类和位运算来一起完成计算,Integer类的highestOneBit方法,取的是其二进制数左侧的最高位1,因为本题的输入参数为正数,可以不用考虑负数、反码、补码的问题。获得最高位所表示的整数后,再左移一位,然后再减1,最后还是和num进行异或运算,并返回结果。

public int findComplement4(int num) {
if (num == 0) {
return 1;
}
int res = (Integer.highestOneBit(num)<<1) - 1;
return num^res;
}

06 第五种解法

还有一种做法,也借助位运算,使用与(&)运算,在进行与运算之前,我们先要把与运算两边的数准备好。左边的数是对num进行非运算,右边的数还是需要借助Integer类的highestOneBit方法,获取最高位1所表示的整数再减去1,然后两个新的数进行与运算,并返回结果。以题目中的5为例:

左边:对5进行非运算,得到-6

右边:5的二进制数最高位1表示为整数4,减去1为3

3

00000000000000000000000000000011

-6

10000000000000000000000000001010

当相同的位上均为1时结果为1,否则结果为0

00000000000000000000000000000010

也就是整数2。

public int findComplement5(int num) {
return ~num & (Integer.highestOneBit(num) - 1);
}

07小结

算法专题目前已日更超过三个月,算法题文章107+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!

LeetCode算法题-Number Complement(Java实现-五种解法)的更多相关文章

  1. LeetCode算法题-Number of Lines To Write String(Java实现)

    这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为 ...

  2. LeetCode算法题-Find the Difference(Java实现-五种解法)

    这是悦乐书的第214次更新,第227篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第82题(顺位题号是389).给定两个字符串s和t,它们只包含小写字母.字符串t由随机混 ...

  3. LeetCode算法题-Number of 1 Bits(Java实现)

    这是悦乐书的第186次更新,第188篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第45题(顺位题号是191).编写一个带无符号整数的函数,并返回它所具有的"1 ...

  4. LeetCode算法题-Number of Boomerangs(Java实现)

    这是悦乐书的第231次更新,第244篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第98题(顺位题号是447).给定平面中的n个点都是成对不同的,"回旋镖&qu ...

  5. LeetCode算法题-Number of Segments in a String(Java实现)

    这是悦乐书的第226次更新,第239篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第93题(顺位题号是434).计算字符串中的段数,其中段定义为非空格字符的连续序列.请注 ...

  6. LeetCode算法题-Third Maximum Number(Java实现-四种解法)

    这是悦乐书的第222次更新,第235篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第89题(顺位题号是414).给定非空的整数数组,返回此数组中的第三个最大数字.如果不存 ...

  7. LeetCode算法题-Missing Number(Java实现-四种解法)

    这是悦乐书的第200次更新,第209篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第65题(顺位题号是268).给定一个包含n个不同数字的数组,取自0,1,2,...,n ...

  8. LeetCode算法题-Ugly Number(Java实现-四种解法)

    这是悦乐书的第199次更新,第208篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第64题(顺位题号是263).编写一个程序来检查给定的数字是否是一个丑陋的数字.丑陋的数 ...

  9. LeetCode算法题-Heaters(Java实现)

    这是悦乐书的第239次更新,第252篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第106题(顺位题号是475).冬天来了!您在比赛期间的第一份工作是设计一个固定温暖半径 ...

随机推荐

  1. Linux篇---Grep和正则匹配

    一.前述 Linux中正则匹配查找比较常用,所以分享一篇关于正则匹配和Grep结合的文章. 二.匹配规则 匹配操作符: \                  转义字符.                 ...

  2. Python内置函数(3)——any

    英文文档: any(iterable) Return True if any element of the iterable is true. If the iterable is empty, re ...

  3. Asp.Net Core WebApi (Swagger+EF Core/Code First)

    Swagger简介: Swagger™的目标是为REST APIs 定义一个标准的,与语言无关的接口,使人和计算机在看不到源码或者看不到文档或者不能通过网络流量检测的情况下能发现和理解各种服务的功能. ...

  4. qt集成dsoframer.ocx打开office办公软件

    最近一段时间真是事情太多了,前不久项目中一个嵌入office软件的问题,由于没有时间研究,且项目的需求是浏览word文档,偷了一个懒,把word文档转换成pdf文档,然后嵌入libcef浏览器给打开了 ...

  5. Android创建或删除了文件,在电脑端查看的时候,却没有对应的变化,处理办法

    在Android应用中,碰到一个问题,在代码中执行创建或者删除某个文件后,在系统的文件管理器中能够相应地看到文件的变化,但是插在电脑上查看的时候,却看不到改文件的变化.同时,当创建文件后,在系统中的某 ...

  6. 把路由器改装成git服务器(OpenWRT环境的GIT服务器搭建)

    在单位中,通常都标配了git服务器用来管理代码. 对于家庭或者小办公室,这种方式有点不经济.当然如果是开源项目就简单了,刚刚被微软收购的github是理想选择.但如果没有打算开源,我今天的话题可能对你 ...

  7. Android:剖析源码,随心所欲控制Toast显示

    前言 Toast相信大家都不会陌生吧,如果对于Toast不甚了解,可以参考我的上一篇博客<Android:谈一谈安卓应用中的Toast情节>,里面有关于Toast基础比较详细的介绍.但是如 ...

  8. PerformanceCounter蛋痛的设计

    在.NET下对进程的性能计数可以使用PerformanceCounter,通过该对象可以对进程的CPU,内存等信息进行统计.对于正常使用来说这个对象还是很方便,但对于同一名称的多个进程进行性能计数那真 ...

  9. 在Java中使用redisTemplate操作缓存

    背景 在最近的项目中,有一个需求是对一个很大的数据库进行查询,数据量大概在几千万条.但同时对查询速度的要求也比较高. 这个数据库之前在没有使用Presto的情况下,使用的是Hive,使用Hive进行一 ...

  10. 【Parallel】.Net 并行执行程序的使用心得

    一.摘要 官方介绍:提供对并行循环和区域的支持. 命名空间:using System.Threading.Tasks 三个静态方法:Parallel.Invoke,Parallel.For,Paral ...