一些刷题小技巧
@[toc]
## 位运算
### 左移 `<<1` 表示 乘以 2,右移 `>>1` 表示除以 2
### 获取一个 int 类型整数每个位置上的 2 进制数位
> ex:[剑指 Offer II 067. 最大的异或 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/ms70jA/)
(下面代码为从高位向低位、从左往右)
```java
for (int i = 31; i >= 0; i --) {
// 获取当前数位上的 2 进制数值
int bit = (num >> i) & 1;
......
}
```
### 从高位向低位(从左往右)计算两个整数的异或结果
> ex:[剑指 Offer II 067. 最大的异或 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/ms70jA/)
```java
// 存储两数(`int nums1` 和 `int nums2`)的异或结果
int xor = 0;
for (int i = 31; i >= 0; i --) {
// 获取当前数位上的 2 进制数值
int bit1 = (num1 >> i) & 1;
int bit2 = (num2 >> i) & 1;
// 两数位不相等
if (bit1 != bit2) {
xor = xor * 2 + 1;
}
// 两数位相等
else {
xor = xor * 2;
}
}
return xor;
```
## 字符串
### 判断字符串 1 是否以 字符串 2 开头
> ex:[剑指 Offer II 114. 外星文字典](https://leetcode.cn/problems/Jf1JuT/)
```java
// String word1 = "abc";
// String word2 = "ab";
word1.startsWith(word2); // true
```
### 判断字符串中的某个字符是否是数字或字母
> ex:[剑指 Offer II 018. 有效的回文](https://leetcode.cn/problems/XltzEq/)
```java
// String s;
char ch1 = s.charAt(left);
boolean res = Character.isLetterOrDigit(ch1);
```
### 某个字符转小写
> ex:[剑指 Offer II 018. 有效的回文](https://leetcode.cn/problems/XltzEq/)
```java
// char ch1;
ch1 = Character.toLowerCase(ch1);
```
## 集合与数组
### 数组复制
> ex:[面试题 17.05. 字母与数字](https://leetcode.cn/problems/find-longest-subarray-lcci/)
```java
// int[] nums1
// 左闭右开
int nums2 = Arrays.copyOfRange(nums1, leftIndex, rightIndex);
```
### 数组快速求和
> ex:[剑指 Offer II 012. 左右两边子数组的和相等 - 力扣(LeetCode)](https://leetcode.cn/problems/tvdfij/)
```java
// int[] nums;
int sum = Arrays.stream(nums).sum();
```
### 数组快速排序
```java
// int[] nums
Arrays.sort(nums); // 该方法返回值是 void
```
### 快速判断两个数组是否相同
> ex:[剑指 Offer II 115. 重建序列 - 力扣(LeetCode)](https://leetcode.cn/problems/ur2n8P/)
```java
// int[] arr1;
// int[] arr2;
boolean res = Arrays.equals(arr1, arr2);
```
### 圆环数组
如果这个数组是一个圆环,那么我们在取下标的时候,假设当前下标是 i:
- 前一个下标:(i - 1 + len) % len
- 后一个下标:(i + 1 + len) % len,或者 (i + 1) % len
### List 快速排序
```java
// List<Integer> list
Collections.sort(list); // 该方法返回值是 void
```
### `List<String>` 转 `String[]`
> ex:[剑指 Offer II 086. 分割回文子字符串 - 力扣(LeetCode)](https://leetcode.cn/problems/M99OJA/)
```java
// List<String> list
list.toArray(new String[list.size()]);
```
### `List<String[]>` 转 `String[][]`
> ex:[剑指 Offer II 086. 分割回文子字符串 - 力扣(LeetCode)](https://leetcode.cn/problems/M99OJA/)
```java
// List<String> list
list.toArray(new String[list.size()][]);
```
### `String[]` 转 `List<String>`
> ex:[剑指 Offer II 109. 开密码锁 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/zlDJc7/)
```java
// String[] str;
List<String> list = Arrays.asList(str);
// 等价于
List<String> list = new ArrayList<>(str);
// Arrays.asList 底层就是调用的 new ArrayList<>()
```
### `String[]` 转 `Set<String>`
Set 的构造函数只接受 Collection 集合对象

所以不能直接用下面代码:
```java
// String[] str
Set<String> set = new HashSet<>(str); // false
```
得把数组转成 list 集合再调用 set 构造函数
```java
// String[] str
Set<String> set = new HashSet<>(Arrays.asList(str)); // true
```
### `List<Integer>` 转 `int[]`
> ex: [剑指 Offer II 113. 课程顺序 - 力扣(LeetCode)](https://leetcode.cn/problems/QA2IGt/)
```java
// List<integer> list;
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
```
先转成 `IntStream`,再转成 `int[]`
等同于:
```java
// List<Integer> list;
IntStream intStream = list.stream().mapToInt(Integer::intValue);
int[] num = intStream.toArray();
```
如下面这样写会报错,`List<Integer>` 调用 toArray 生成的是 `Integer[]` 而不是 `int[]`

### `int[]` 转 `List<Integer>`
> ex:[349. 两个数组的交集 - 力扣(LeetCode)](https://leetcode.cn/problems/intersection-of-two-arrays/)
注意**不能**像 `String[]` 转 `List<String>` 这样转换:
```java
// int[] arr;
List<Integer> list = new ArrayList<>(Arrays.asList<>(arr));
```
ArrayList 的构造函数需要接收形如 `List<Integer>` 的构造参数,而不能是 `List<int>` 这样的
所以我们需要先把 `int[]` 转成 `Integer[]`
```java
// int[] arr
Integer[] arrInteger = Arrays.stream(arr).boxed().toArray(Integer[]::new);
List<Integer> list = Arrays.asList(arrInteger);
// Set<Integer> set = new HashSet<>(Arrays.asList(arrInteger));
```
记不住就直接 for-each 遍历添加吧,还简单点:
```java
// int[] arr
List<Integer> list = new ArrayList<>();
for (int num : arr) {
list.add(num);
}
```
### Map 中添加元素
> ex: [剑指 Offer II 113. 课程顺序 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/QA2IGt/)
```java
// Map<String, List<String>> map;
map.putIfAbsent("xxx", new ArrayList<>()); // 若 key 不存在,则添加 key
map.get("xxx").append("111"); // 为 key 对应的 value 赋值
// Map<String, Integer> map;
map.putIfAbsent("xxx", 0); // 若 key 不存在,则添加 key
map.put("xxx", map.get("xxx") + 1); // 将 key 对应的 value 值 + 1
```
