题目描述:
给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
示例 1:
输入:nums = [1,0,-1,0,-2,2], target = 0
输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
示例 2:
输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]
剪枝:
- 当排序后前面四个数之和>target,说明往后循环i无论如何也不能满足条件了,此时break直接跳出
- 确定第一和第二个数之后,直接与length-1和length-2…下标的数相加,如果
- 第一层循环
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
- 第二层循环
if(j > i + 1 && nums[j] == nums[j - 1]) continue;二、双指针,如果==的时候,需要将左指针移动到不同的数,右指针也要移动到不同的数,方便得到的结果不同。 可通过完整代码:
public static ListLeetCode 17电话号码的字母组合> fourSum(int[] nums, int target) { List
> list = new ArrayList<>(); int length = nums.length; if (length < 4) return list; Arrays.sort(nums); // 先排序 for (int i = 0; i < length - 3; i++) { //
0 && nums[i] == nums[i - 1]) continue; // 同一重循环中,如果当前元素与上一个元素相同,则跳过当前元素。【因为一次i之后的元素上一次通过j=i+1已经枚举过了】 if ((long) nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) break; // 剪枝:如果前面4个之和【最小的4个和】>target,说明后面的循环i也没有机会==了 if ((long) nums[i] + nums[length- 1] + nums[length- 2] + nums[length- 3] < target) continue; // 本次nums[i]加上倒数三个【本次最大的4个和,淘汰本次后面的枚举】 if (j > i + 1 && nums[j] == nums[j - 1]) continue; if ((long) nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) break; if ((long) nums[i] + nums[j] + nums[length- 1] + nums[length- 2] < target) continue; int left = j + 1, right = length- 1; while (left < right) { int sum = nums[i] + nums[j] + nums[left] + nums[right]; if (sum == target) { list.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right])); while (left + 1 < right && nums[left] == nums[left + 1]) left++; left++; while (left < right - 1 && nums[right] == nums[right - 1]) right--; right--; } else if (sum < target) { left++; } else { right--; } } } } return list; }
题目描述:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:
输入:digits = “”
输出:[]
示例 3:
输入:digits = “2”
输出:[“a”,“b”,“c”]
注意Map中这样直接添加元素:
Map可通过完整代码如下:phoneMap = new HashMap () {{ put('2', "abc"); put('3', "def"); put('4', "ghi"); put('5', "jkl"); put('6', "mno"); put('7', "pqrs"); put('8', "tuv"); put('9', "wxyz"); }};
public ListLeetCode 347前k个高频元素(数组中)letterCombinations(String digits) { List ans = new ArrayList<>(); if (digits.length() == 0) return ans; Map phoneMap = new HashMap () {{ put('2', "abc"); put('3', "def"); put('4', "ghi"); put('5', "jkl"); put('6', "mno"); put('7', "pqrs"); put('8', "tuv"); put('9', "wxyz"); }}; dfs(ans, phoneMap, digits, 0, new StringBuffer()); return ans; } private void dfs(List ans, Map phoneMap, String digits, int index, StringBuffer sub) { if (index == digits.length()) { // 添加一个变为1,添加n个变为n ans.add(sub.toString()); } else { char digit = digits.charAt(index); String letters = phoneMap.get(digit); // 例:得到abc for (int i = 0; i < letters.length(); i++) { // 遍历添加a、b、c sub.append(letters.charAt(i)); dfs(ans, phoneMap, digits, index + 1, sub); // 如果是数字2,就分三个分支回溯 sub.deleteCharAt(index); // 删除sub添加的第一个元素(abc中的一个) } } }
题目描述:
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
遍历Map使用
for (Map.Entry优先级队列默认从小到大排列(默认小顶堆,但是我们装进去的是数组,所以这里需要修改一下比较器)entry : map.entrySet()) { // 遍历k个不同的数字 int num = entry.getKey(), count = entry.getValue(); }
直接修改()中的new Comparator idea就会弹出提示
PriorityQueue可通过完整代码如下:queue = new PriorityQueue<>(new Comparator () { // 优先级队列中元素为一个2元素数组[num, count] @Override public int compare(int[] o1, int[] o2) { return o1[1] - o2[1]; // 优先级队列中数组元素,按照索引[1](次数)从小到大 } });
public int[] topKFrequent(int[] nums, int k) {
Map map = new HashMap<>();
for (int n : nums) { // 记录数组中各个int出现的次数
map.put(n, map.getOrDefault(n, 0) + 1);
}
PriorityQueue queue = new PriorityQueue<>(new Comparator() { // 优先级队列中元素为一个2元素数组[num, count]
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1]; // 优先级队列中数组元素,按照索引[1](次数)从小到大
}
});
for (Map.Entry entry : map.entrySet()) { // 遍历k个不同的数字
int num = entry.getKey(), count = entry.getValue();
if (queue.size() == k) {
if (count > queue.peek()[1]) {
queue.poll();
queue.add(new int[]{num, count});
}
} else {
queue.offer(new int[]{num, count});
}
}
// 返回数组
int[] ret = new int[k];
for (int i = 0; i < k; i++) {
ret[i] = queue.poll()[0]; // 弹出栈顶元素
}
return ret;
}



