一个小技巧是:用一个长度为26的字符串作为哈希表("23321222122233111121131313")。
class Solution {
public String[] findWords(String[] words) {
// 字符串即哈希表
String rowIndex = "23321222122233111121131313";
List<String> resList = new ArrayList<>();
for (String word : words) {
// 每个单词的第一个字符,作为标准行号,之后的字符行号(包括第一个字符)与其对比
char index = rowIndex.charAt(Character.toLowerCase(word.charAt(0)) - 'a');
boolean flag = true;
for (char c : word.toCharArray()) {
if (rowIndex.charAt(Character.toLowerCase(c) - 'a') != index) {
flag = false;
break;
}
}
if (flag) {
resList.add(word);
}
}
// 转化一下结果
String[] resArr = new String[resList.size()];
for (int i = 0; i < resList.size(); i++) {
resArr[i] = resList.get(i);
}
return resArr;
}
}
看到"子序列"其实可以立马想到"动态规划"。
我们当然可以多用一层for循环:if (arr[i] - arr[j] == diff) dp[i] = Math.max(dp[i - 1], dp[j] + 1)
优化的方案使用使用HashMap进行降维:map.put(n, map.getOrDefault(n - diff, 0) + 1)
class Solution {
public int longestSubsequence(int[] arr, int difference) {
Map<Integer, Integer> map = new HashMap<>();
int res = 0;
for (int n : arr) {
map.put(n, map.getOrDefault(n - difference, 0) + 1);
res = Math.max(res, map.get(n));
}
return res;
}
}
求和法:求出如果不缺失数字的数组和,再求出实际的数组和,作差即可得到缺失的数字
位运算:给大小为n的缺失数组补上大小为n+1的不缺失数组,就转化为了只出现一次的数字问题
class Solution {
public int missingNumber(int[] nums) {
// 求和法(求出如果不缺失数字的数组和,再求出实际的数组和,作差即可得到缺失的数字)
int len = nums.length;
int relSum = len * (len + 1) / 2;
int arrSum = 0;
for (int num : nums) {
arrSum += num;
}
return relSum - arrSum;
// 位运算(给大小为n的缺失数组补上大小为n+1的不缺失数组,就转化为了只出现一次的数字问题)
int xor = 0;
for (int i = 1; i <= nums.length; i++) {
xor ^= i;
}
for (int num : nums) {
xor ^= num;
}
return xor;
}
}
检索标记:1218. 最长定差子序列给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。子序列 是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从 arr 派生出来的序列。500. 键盘行给你一个字符串数组 words ,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。美式键盘 中:第一行由字符 “qwertyuiop” 组成。第二行由字符 “asdfghjkl” 组成。第三行由字符 “zxcvbnm” 组成。268. 丢失的数字给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。