最近在刷leetcode题,一些代码技巧和思路想要能记录下来,所以写了这篇博客,因为leetcode会继续刷下去,所以每当有笔记也会在这里持续更新。
1.位运算:
- n & n-1:将n的二进制表示中的最后为1的那位改为0
//该代码为判断n中是否只有一个1
return n & (n-1) == 0
-
n >> 1:逻辑右移一位,相当于将n除以2
-
i>>j &1:把 i 算术右移 j 位,然后检测最低位是否为1,此操作可用于判断某个数字的二进制表示中有多少个1,比如:
//该代码的sum即为tmp的二进制表示中有多少位1
int sum = 0;
while (tmp != 0){
if ((tmp & 1) == 1)
sum ++;
tmp = tmp >> 1;
}
return sum;
2.将数字字符串转为int数字:
String str = "25578"
int num = 0;
for(int i=0; i<str.length(); i++){
num = num*10 + str.charAt(i)-'0';
}
3.判断是否是回文字符串:
public boolean isPalindrome(String sb, int start, int end){
for (int i=start,j=end; i<j; i++,j--){
if (sb.charAt(i) != sb.charAt(j))
return false;
}
return true;
}
4.二分法的两种写法
题目:传入一个数组nums,查询目标值target,返回target的下标
- 写法1:
public int search(int[] nums, int target){
if (nums.length == 0)
return -1;
int left = 0, right = nums.length;
while (left < right){
int mid = (left+right)/2;
if (nums[mid] == target){
return mid;
}else if (nums[mid] > target){
right = mid;
}else
left = mid+1;
}
return -1;
}
- 写法2:
public int search(int[] nums, int target){
if (nums.length == 0)
return -1;
int left = 0, right = nums.length-1;
while (left <= right){
int mid = (left+right)/2;
if (nums[mid] == target){
return mid;
}else if (nums[mid] > target){
right = mid-1;
}else
left = mid+1;
}
return -1;
}
注意两者的区别,有三个地方不同,涉及到循环不变量,要好好体会。二分法不难想,但要写对需要想好边界条件,使用循环不变量去控制边界条件有助于理解代码怎么写

要理解循环不变量可以参考这篇帖子: 二分查找的 ”循环不变量“ , 只要理解, 根本不用死记硬背边界条件
5.判断小写字母组成的字符串是否有重复的字母
private boolean match(StringBuilder builder) {
String s = builder.toString();
int[] counter = new int[26];
for (int i = 0; i < s.length(); i++) {
int ch = s.charAt(i)-'a';
counter[ch]++;
if (counter[ch] > 1) {
return false;
}
}
return true;
}
6.判断两个数组是否相等
Arrays.equals(arr1, arr2)
7.判断字符串是否包含某个字符
char c = s2.charAt(0);
s1.contains(String.valueOf(c));
8.使用异或运算转换字母大小写
大写字母 A-Z 的 ASCII 码范围为 [65, 90];
小写字母 a-z 的 ASCII 码范围为 [97, 122];
65 + 32 = 01000001 + 00100000 = 01100001,即 97。 总结:
大变小,小变大( 大写变小写、小写变大写 ): 字符 ^= 32
大变小 (大写变小写、小写变小写 ): 字符 |= 32
小变大 (小写变大写、大写变大写 ): 字符 &= -33
9.排序
算法题中的排序一般有两种,一种是数组排序,一种是对象排序。
假设存在一个二维数组
intervals = [[1,3],[2,6],[8,10],[15,18]],想对二维矩阵的数组按照左端点从小到大排序,可以样做:
Arrays.sort(intervals, (p, q) -> p[0] - q[0]);
10.列表转为二维数组
List<int[]> merged = new ArrayList<>();
merged.sort((p,q) -> p[0]-q[0]);
int[][] res = merged.toArray(new int[merged.size()][]);