基础知识点
判断一个数是否是2的幂次
方法一:位运算
所有2的幂次数的二进制表示中有且仅有一个1,进行位运算 n&(n-1) 后结果为0
- 检查正数:n > 0(负数和0不是2的幂次)
- 位运算: n & ( n -1) 会消去二进制中最低为的1
- 如果是2的幂次,消去后结果为0
- eg:8(1000)& 7(0111) = 0
方法二:数学除法
不断将数除以2,若最终结果为1则是2的幂次
- 处理边界:若 n <= 0,直接返回false,不是
- 循环除以2:直到无法被2整除
- 结果判断:若最终余数为1,则是2的幂次
方法三:对数运算
利用数学公式 log2(n) 是否为整数,是整数就是的2的幂次
if (n <= 0 ) return false;
double log = Math.log(n) / Math.log(2);
return Math.abs(log - Math.round(log)) < 1e-10; // 处理浮点精度误差
方法四:二进制中1的个数
统计二进制中1的个数是否为1。如果大于0并且二进制中只有一位1,是整数就是2的幂次
return n > 0 && Integer.bitCount(n) == 1;
位运算
1.按位与(AND)&
&:两个数的对应二进制位均为1时,结果位才为1
- 判断奇偶性:x&1 == 0
偶数结果为0
2.按位或(OR)|
|:两个数的对应二进制位有一个为1,结果位即为1
3.按位异或(XOR)^
两个数的对应二进制位不同时结果为1,相同时为0。(异1同0)
4.按位非(NOT)~
对一个数的每一位取反(0变1,1变0)
5.左移(Left Shift)<< 乘法
将二进制位整体左移,右侧补0
6.右移 >> 除法
将二进制位整体右移,左侧补符号位(正数补0,负数补1)
bitCount()
属于Integer类和Long类的,计算整数二进制中表示1的个数
题
1.回文数组 - 蓝桥云课
package com.lanqiao;
import java.util.*;
public class Main {public static void main(String[] args){final int N = 100100;long[] nums = new long[N];long[] difs = new long[N];Scanner scan = new Scanner(System.in);int n = scan.nextInt();for(int i = 0; i < n; i++)nums[i] = scan.nextInt();int left = 0, right = n-1, j = 0;while(left < right)difs[j++] = nums[right--] - nums[left++];long count = 0;for(int i = 0; i < n/2; i++) {// 相邻为正if(difs[i] > 0 && difs[i+1] > 0) {// 后面数大于前面数if(difs[i] < difs[i+1]) {count += Math.min(difs[i], difs[i+1]);difs[i+1] -= difs[i];}else {count += Math.max(difs[i], difs[i+1]);i++;}}// 相邻为负else if(difs[i] < 0 && difs[i+1] < 0) {// 后面数大于前面数 此时后面数与0更短if(difs[i] < difs[i+1]) {count += Math.abs(Math.min(difs[i], difs[i+1]));i++;}else { // -20 -144count += Math.abs(Math.max(difs[i], difs[i+1]));difs[i+1] -= difs[i];}}// 相邻异号elsecount += Math.abs(difs[i]);}System.out.println(count);scan.close();}
}
2.Excel地址 - 蓝桥云课
我的老母,真十一步一步。。。走的很艰难。。。
import java.util.*;public class Main {public static void main(String[] args) {Scanner scan = new Scanner(System.in);int num = scan.nextInt();Map<Integer, Character> map = new HashMap<>();map.put(0, 'Z');for(int i = 1; i <= 25; i++){map.put(i, (char)(64+i));}String res = "";while(num > 0) {res += map.get(num%26);if(num%26 == 0)num = (num-1) / 26; elsenum /= 26;}System.out.println(new StringBuilder(res).reverse().toString());scan.close();}
}
这个的关键点就是,Excel进制是A~Z,对应1~26。
当余数为0的时候,对应Z,而不是A;余数1~25对应字母A~Y。
所以当余数为0时,需要将商调整为 (num-1)/26,避免多算一轮进位