java中负3与3异或_LeetCode刷题笔记(3)Java位运算符与使用按位异或(进制之间的转换)...

1.问题描述

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

算法应该具有线性时间复杂度并且不使用额外空间。

输入: [4,1,2,1,2]

输出:4

2.解题思路

这道题的主要的难点是具有线性时间复杂度并且不能使用额外的空间,因此就排除了很多的方法。

当时使用双指针尝试了以下,但是并没有取得成功,因为最后的结果可能是错误的。

3.正确解题思路

使用“按位异或”,即Java中的‘^’运算符来进行计算。

由于异或的原则是,不同为1,相同为0,题目中给定的数组中,如果两个相同的数异或的结果一定为0,最后得到的结果就是只出现一次的元素。

public int singleNumber(int[] nums) {int res = nums[0];for (int i = 1; i < nums.length; i++) {

res^=nums[i];

}returnres;

}

4.另外的一个例子

需要找出t中不在s中的那个字符。

输入:

s= "abcd"t= "abcde"输出:

e

也可以用按位异或的方式进行计算

public charfindTheDifference(String s, String t) {char c = 0;for (int i = 0; i < s.length(); ++i) {

c^=s.charAt(i);

}for (int i = 0; i < t.length(); ++i) {

c^=t.charAt(i);

}returnc;

}

5.问题描述

不使用“+”“-”运算符计算两个整数的和。

(1)自己的思路:模拟计算机实际来操作二进制数补码的加法

Integer.parseInt无法将一个负数的补码转换成原始的负数,否则会报错java.lang.NumberFormatException

此时,只能这么来计算:取反码,然后加1,转换成相反数,然后添加上一个符号“-”

//System.out.println(new e371().getSum(a, b));

System.out.println("11111111111111111111111111101100".length());

System.out.println(Integer.toBinaryString(-20));//System.out.println(Integer.parseInt("11111111111111111111111111101100", 2));

System.out.println(Integer.parseInt("00000000000000000000000000010100", 2));

解题思路:模仿实际计算机的真实计算结果,超级麻烦!!!!!!

classSolution {public int getSum(int a, intb) {

String aStr=Integer.toBinaryString(a);

String bStr=Integer.toBinaryString(b);

String longStr= (aStr.length() < bStr.length()) ?bStr : aStr;

String shortStr= (aStr.length() < bStr.length()) ?aStr : bStr;

StringBuffer sb= newStringBuffer();for (int i = 0; i < longStr.length() - shortStr.length(); i++) {

sb.append(0);

}

shortStr=sb.toString().concat(shortStr);boolean isUp = false;

StringBuffer resSB= newStringBuffer();for (int i = longStr.length() - 1; i >= 0; i--) {if (!isUp) {if (longStr.charAt(i)== '1' && shortStr.charAt(i) == '1') {

isUp= true;

resSB.append(0);

}else{

resSB.append(Integer.valueOf(longStr.charAt(i))^Integer.valueOf(shortStr.charAt(i)));

}

}else{if (longStr.charAt(i) == '1' && shortStr.charAt(i) == '1') {

isUp= true;

resSB.append(1);

}else if (longStr.charAt(i) == '0' && shortStr.charAt(i)== '0') {

resSB.append(1);

isUp= false;

}else{

resSB.append(0);

isUp= true;

}

}

}if (isUp && resSB.length() < 32) resSB.append(1);

String result=resSB.reverse().toString();if (result.length() < 32) {return Integer.parseInt(result, 2);

}if (result.charAt(0) == '0') {return Integer.parseInt(result, 2);

}else{

StringBuffer sbsb= newStringBuffer();for (charc : result.toCharArray()) {if (c == '1') {

sbsb.append(0);

}else{

sbsb.append(1);

}

}

result=sbsb.toString();

longStr=result;

shortStr= "00000000000000000000000000000001";boolean isUp_1 = false;

StringBuffer resSB_1= newStringBuffer();for (int i = longStr.length() - 1; i >= 0; i--) {if (!isUp_1) {if (longStr.charAt(i)== '1' && shortStr.charAt(i) == '1') {

isUp_1= true;

resSB_1.append(0);

}else{

resSB_1.append(Integer.valueOf(longStr.charAt(i))^Integer.valueOf(shortStr.charAt(i)));

}

}else{if (longStr.charAt(i) == '1' && shortStr.charAt(i) == '1') {

isUp_1= true;

resSB_1.append(1);

}else if (longStr.charAt(i) == '0' && shortStr.charAt(i)== '0') {

resSB_1.append(1);

isUp_1= false;

}else{

resSB_1.append(0);

isUp_1= true;

}

}

}

result=resSB_1.reverse().toString();return -Integer.parseInt(result, 2);

}

}

}

(2)更好的思路,使用位运算符

public int getSum(int a, intb) {if(b == 0){ //没有进位的时候完成运算

returna;

}intsum,carry;

sum= a^b; //完成第一步加法的运算

carry = (a&b)<<1; //完成第二步进位并且左移运算

return getSum(sum,carry);// }

根据实际例子分析这块代码:

(1)a=1,b=2

a-> 00000000 00000000 00000000 00000001

b-> 00000000 00000000 00000000 00000010

b=2

sum-> 00000000 00000000 00000000 00000011

a&b-> 00000000 00000000 00000000 00000000

carry-> 00000000 00000000 00000000 00000000 输出sum=3

(2)a=1,b=7

a-> 00000000 00000000 00000000 00000001

b-> 00000000 00000000 00000000 00000111

a&b-> 00000000 00000000 00000000 00000001

sum-> 00000000 00000000 00000000 00000110

carry-> 00000000 00000000 00000000 00000010

a&b-> 00000000 00000000 00000000 00000010

sum-> 00000000 00000000 00000000 00000100

carry-> 00000000 00000000 00000000 00000100

a&b-> 00000000 00000000 00000000 00000100

sum-> 00000000 00000000 00000000 00000000

carry-> 00000000 00000000 00000000 00001000

a&b-> 00000000 00000000 00000000 00000000

sum-> 00000000 00000000 00000000 00001000

carry-> 00000000 00000000 00000000 00000000 输出sum = 8

(3)a=-16,b=14

a-> 11111111111111111111111111110000

b-> 00000000000000000000000000001110

a&b-> 00000000000000000000000000000000

sum-> 11111111111111111111111111111110

carry-> 0 输出sum=-2

6.Java位运算符

(1)”~(按位取反)”

~(-14) == 13(int类型)-14(原码):10000000 00000000 00000000 00001110

-14(反码):11111111 11111111 11111111 11110001

-14(补码):11111111 11111111 11111111 11110010非过程(同时为1才为1):00000000 00000000 00000000 00001101十进制表示为:1+4+8=13

(2)”&(按位与)”

5&-4 == 4(int类型)

-4(原码):10000000 00000000 00000000 00000100

-4(反码):11111111 11111111 11111111 11111011

-4(补码):11111111 11111111 11111111 11111100

5 : 00000000 00000000 00000000 00000101

-4: 11111111 11111111 11111111 11111100与过程(同时为1才为1):

00000000 00000000 00000000 00000100十进制表示为:4

(3)”|(按位或)”

3|6 == 7(int类型)3: 00000000 00000000 00000000 00000011

6: 00000000 00000000 00000000 00000110或过程(只要有1就为1):00000000 00000000 00000000 00000111十进制表示为:1+2+4=7

(4)”^(按位异或)”

10^3 == 9(int类型)3 : 00000000 00000000 00000000 00000011

10: 00000000 00000000 00000000 00001010异或过程(不同为1相同为0):00000000 00000000 00000000 00001001十进制表示为:1+8=9

(5)”<

-2<<3 == -16(int类型)

-2 : 11111111 11111111 11111111 11111110<

(6)”>>(右移,高位添符号位)”

15>>2 == 3(int类型)

15 : (符号位是0)00000000 00000000 00000000 00001111

>>过程:00(补两个0) 000000 00000000 00000000 00000011 11(舍弃最末位两个11)十进制表示为:1+2=3

(7)”>>>(右移,高位添0补齐)”

4>>>2 == 1(int类型)

4 : 00000000 00000000 00000000 00000100

>>>过程:00(补两个0) 000000 00000000 00000000 00000001 00(舍弃最末位两个00)

十进制表示为:1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值