3、查找表相关问题
1、两类查找问题
1.1、两个数组的交集
public static int[] intersection(int[] nums1, int[] nums2) { Set<Integer> set = new HashSet<>(); for (int i : nums1) set.add(i); Set<Integer> res = new HashSet<>(); for (int i : nums2) { if (set.contains(i)) res.add(i); } return res.stream().mapToInt(Integer::intValue).toArray(); }
1.2、两个数组的交集 II
public static int[] intersect(int[] nums1, int[] nums2) { Map<Integer, Integer> map = new HashMap<>(); for (int i : nums1) map.put(i, map.getOrDefault(i, 0) + 1); List<Integer> list = new ArrayList<>(); for (int i : nums2) { if (map.getOrDefault(i, 0) != 0) { list.add(i); map.put(i, map.get(i) - 1); } } return list.stream().mapToInt(Integer::intValue).toArray(); }
2、Set 和 Map 不同底层实现的区别
更多问题
242 - 有效的字母异位词
202 - 快乐数
290 - 单词规律
205 - 同构字符串
451 - 根据字符出现频率排序
3、两数之和
public static int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = new HashMap<>(); // value : index for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) return new int[]{i, map.get(complement)}; else map.put(nums[i], i); } throw new IllegalArgumentException("The input has no solution"); }
4、灵活选择键值
4.1、四数相加 II
public static int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { // Key -> i + j, Value -> 个数 Map<Integer, Integer> map = new HashMap<>(); for (int i : nums1) { for (int j : nums2) { int sum = i + j; map.put(sum, map.getOrDefault(sum, 0) + 1); } } int res = 0; for (int k : nums3) { for (int l : nums4) { int sum = k + l; res += map.getOrDefault(-sum, 0); } } return res; }
更多问题
49 - 字母异位词分组
4.2、回旋镖的数量
/** * (i, j, k) 使得 distance(points[i], points[j]) == distance(points[i], points[k]) */ public static int numberOfBoomerangs(int[][] points) { int res = 0; for (int i = 0; i < points.length; i++) { // Key -> distance(point[i] ,point[x]), Value -> 个数 Map<Integer, Integer> map = new HashMap<>(); for (int x = 0; x < points.length; x++) { if (x == i) continue; int distance = getDistance(points[i], points[x]); map.put(distance, map.getOrDefault(distance, 0) + 1); } for (int value : map.values()) { if (value >= 2) res += value * (value - 1); } } return res; } public static int getDistance(int[] pointA, int[] pointB) { int xDiff = pointA[0] - pointB[0]; int yDiff = pointA[1] - pointB[1]; return (xDiff * xDiff) + (yDiff * yDiff); }
更多问题
149 - 直线上最多的点数
5、滑动窗口 + 查找表
219 - 存在重复元素 II
推荐 containsNearbyDuplicate2
public static boolean containsNearbyDuplicate1(int[] nums, int k) { // nums[l ... r] 是滑动窗口 int l = 0; int r = Math.min(l + k, nums.length - 1); Set<Integer> set = new HashSet<>(); for (int i = l; i <= r; i++) { if (set.contains(nums[i])) return true; set.add(nums[i]); } while (r + 1 < nums.length) { set.remove(nums[l++]); r++; if (set.contains(nums[r])) return true; set.add(nums[r]); } return false; } public static boolean containsNearbyDuplicate2(int[] nums, int k) { Set<Integer> set = new HashSet<>(); // 窗口大小为 k + 1 for (int i = 0; i < nums.length; i++) { if (set.contains(nums[i])) return true; else set.add(nums[i]); // 保持 set 中最多有 k 个元素 if (set.size() == k + 1) set.remove(nums[i - k]); } return false; }
更多问题
217 - 存在重复元素
6、二分搜索树底层实现的顺序性
public static boolean containsNearbyAlmostDuplicate1(int[] nums, int indexDiff, int valueDiff) { TreeSet<Long> set = new TreeSet<>(); // 窗口大小为 indexDiff + 1 for (int i = 0; i < nums.length; i++) { // [min ... max] = [num - valueDiff ... num + valueDiff] int num = nums[i]; long min = num - valueDiff; long max = num + valueDiff; Long ceiling = set.ceiling(min); if (ceiling != null && ceiling <= max) return true; else set.add((long) num); // 保持 set 中最多有 indexDiff 个元素 if (set.size() == indexDiff + 1) set.remove((long) nums[i - indexDiff]); } return false; } public static boolean containsNearbyAlmostDuplicate2(int[] nums, int indexDiff, int valueDiff) { TreeSet<Long> set = new TreeSet<>(); // 窗口大小为 indexDiff + 1 for (int i = 0; i < nums.length; i++) { // [min ... max] = [num - valueDiff ... num + valueDiff] int num = nums[i]; long min = num - valueDiff; long max = num + valueDiff; Long floor = set.floor(max); if (floor != null && floor >= min) return true; else set.add((long) num); if (set.size() == indexDiff + 1) set.remove((long) nums[i - indexDiff]); } return false; }
本文来自博客园,作者:lidongdongdong~,转载请注明原文链接:https://www.cnblogs.com/lidong422339/p/17382802.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步