leetcode刷题小技巧总结(持续更新...)

1,298 阅读3分钟

最近在刷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;
    }

注意两者的区别,有三个地方不同,涉及到循环不变量,要好好体会。二分法不难想,但要写对需要想好边界条件,使用循环不变量去控制边界条件有助于理解代码怎么写

image.png

要理解循环不变量可以参考这篇帖子: 二分查找的 ”循环不变量“ , 只要理解, 根本不用死记硬背边界条件

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()][]);