leetcode268. 丢失的数字
https://leetcode-cn.com/problems/missing-number/
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
解法一:数学法,计算0到n的和,然后减去数组中的值。当值为0,则缺失数字为n,当值不为0,就是其结果
解法二:位运算中的异或。不是要找缺失的数字吗
0,1, 2, 3, 4, 5
0,1, 2, 4, 5
由于异或相同为0,不同为1。来两次就可以找到不同的值
public int missingNumber(int[] nums) {
int res = 0;
for (int i = 0; i < nums.length; i++) {
res ^= nums[i];
res ^= i;
}
return res^nums.length;
}
leetcode1720. 解码异或后的数组
https://leetcode-cn.com/problems/decode-xored-array/
未知 整数数组 arr 由 n 个非负整数组成。
经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] = arr[i] XOR arr[i + 1] 。例如,arr = [1,0,2,1] 经编码后得到 encoded = [1,2,3] 。
给你编码后的数组 encoded 和原数组 arr 的第一个元素 first(arr[0])。
请解码返回原数组 arr 。可以证明答案存在并且是唯一的。
解法:由于题目由异或得来,再异或回去一把就是原值
public int[] decode(int[] encoded, int first) {
int[] arr = new int[encoded.length+1];
arr[0] = first;
int len = encoded.length;
for(int i = 0; i<len; i++){
arr[i+1] = arr[i] ^ encoded[i];
}
return arr;
}
leetcode405. 数字转换为十六进制数
** https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
解法:这题限制用api去解决问题,咱们只能手动来模拟
15与数字与得末尾,无符号右移4位,相当于除以16。
public String toHex(int num) {
char[] s = "0123456789abcdef".toCharArray(); //字符串转数组
if(num == 0) return "0";
StringBuffer buffer = new StringBuffer();
while(num != 0) {
buffer.append(s[num & 15]);
num = num >>> 4; //无符号右移
}
return buffer.reverse().toString();
}
leetcode231. 2的幂
https://leetcode-cn.com/problems/power-of-two/
给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
解法:负数和0直接false,当1个数是2的幂次方, 100。。。000,减一为011。。。111.二者相与为0
public boolean isPowerOfTwo(int n) {
if(n <= 0) return false;
int t = n & (n-1);
if(t == 0) return true;
return false;
}
leetcode 面试题 05.01. 插入
https://leetcode-cn.com/problems/insert-into-bits-lcci/
给定两个整型数字 N 与 M,以及表示比特位置的 i 与 j(i <= j,且从 0 位开始计算)。
编写一种方法,使 M 对应的二进制数字插入 N 对应的二进制数字的第 i ~ j 位区域,不足之处用 0 补齐。
解法:题目意思很简单,就是将中间的一块换成给定的数字
1:让i,j之间的二进制为0001111000
2:取反得到i,j之外的二进制数,中间i,j为0,其余为1110000111
3:与数字n相与得.。。。0000。。。
4 :与m左移i位或运算得答案。。。xxxxx。。。
public static int insertBits(int N, int M, int i, int j) {
int t = 0;
for (int k = i; k <= j; k++) {
t = t |(1 << k);
}
t = ~t;
t = t & N;
t = t |(M << i);
return t;
}
leetcode371. 两整数之和
https://leetcode-cn.com/problems/sum-of-two-integers/
不使用运算符 + 和 - ,计算两整数 a 、b 之和。
解法:a^b异或其实是无进位累加的和 a^b +(a&b) << 1
1.两个整数a, b; a ^ b是无进位的相加;
2.a&b得到每一位的进位,然后左移1位
3.让无进位相加的结果与进位不断的异或,直到进位为0;
public int getSum(int a, int b) {
int t, c;
while(b != 0){
t = a ^ b;
c = (a & b) << 1;
a = t;
b = c;
}
return a;
}
leetcode136. 只出现一次的数字
https://leetcode-cn.com/problems/single-number/
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
解法:由于异或的特性,相同为0,不同为1,所有找单个,异或解决。
public int singleNumber(int[] nums) {
int res = 0;
for(int i = 0; i< nums.length; i++){
res ^= nums[i];
}
return res;
}
l
leetcode 位1的个数
https://leetcode-cn.com/problems/number-of-1-bits/
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数
解法:其实就是跟所在的1进行与运算,当不为0,则当前位为1;1左移i位得到i的位数为1
public int hammingWeight(int n) {
int count = 0;
int t, k = 1;
for (int i = 0; i < 32; i++) {
t = n & k;
if(t != 0) count++;
k <<= 1;
}
return count;
}
leetcode 二进制手表
https://leetcode-cn.com/problems/binary-watch/
解法一:回溯加剪枝
解法二:直接暴力破解,用bitCount来统计1的个数即灯的个数。
public List<String> readBinaryWatch(int num) {
int count = 0;
List<String> list = new ArrayList<>();
if(num > 8) return list;
for (int i = 0; i < 12; i++) {
count = Integer.bitCount(i);
for (int j = 0; j < 60; j++) {
if (count+Integer.bitCount(j) == num) {
list.add(String.format("%d:%02d",i,j));;
}
}
}
return list;
}
leetcode169. 多数元素
https://leetcode-cn.com/problems/majority-element/
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
解法:同归于尽
先当前的count是否为0,如果为0,将当前值当结果值用,count置1,不为0,相等加1,不等减一,最后得结果值
public int majorityElement(int[] nums) {
int count = 0;
int k = 0;
for (int i = 0; i < nums.length; i++) {
if(count == 0) {
k = nums[i];
count = 1;
}else {
if (k == nums[i]) count++;
else count--;
}
}
return k;
}
leetcode面试题 05.07. 配对交换
https://leetcode-cn.com/problems/exchange-lcci/
配对交换。编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。
解法:位运算,&运算取得奇数位,偶数位, 然后奇数位左移1位进行|运算,偶数位右移1位进行|运算
public static int exchangeBits(int num) {
int res = 0;
for (int i = 0; i < 30; i+=2) {
int x = num & (1 << i);
int y = num & (1 << (i+1));
res |= (x << 1);
res |= (y >> 1);
}
return res;
}
leetcode 面试题 16.07. 最大数值
https://leetcode-cn.com/problems/maximum-lcci/
编写一个方法,找出两个数字a和b中最大的那一个。不得使用if-else或其他比较运算符。
解法:不能用比较值,那我就用(a+b+Math.abs(a-b))/2,不过a+b或者a-b会溢出,加一个
public int maximum(int a, int b) {
long t = (((long)a+b)+Math.abs(((long)a-b)))/2;
return (int)t;
}
位运算,用于交换a,b的值
a = a ^ b;
b = a ^ b;
a = a ^ b;