两数之和 = target,找出所有不重复的组合?

1 个回答

  • Hobbit霍比特人
    生活就是这样,别人看到的是结果,而自己撑的是整个过程。
    ## 思路 A(推荐):排序 + 双指针(天然去重) * 对数组排序; * 设左右指针 `l/r`,若 `nums[l] + nums[r] == target` 记录一对 `(nums[l], nums[r])`; * 然后**跳过相同值**(`while l<r && nums[l]==nums[l+1] l++`;右侧同理); * 如果和小了就 `l++`,大了就 `r--`; * 由于已排序且跳重,结果天然无重复。 * 复杂度:时间 `O(n log n)`(排序),空间 `O(1)`(不算输出)。 ### 代码 ```java import java.util.*; public class TwoSumAllPairs { public static List<List<Integer>> twoSumAllUnique(int[] nums, int target) { Arrays.sort(nums); List<List<Integer>> ans = new ArrayList<>(); int l = 0, r = nums.length - 1; while (l < r) { long sum = (long) nums[l] + nums[r]; // 防溢出 if (sum == target) { ans.add(Arrays.asList(nums[l], nums[r])); int lv = nums[l], rv = nums[r]; while (l < r && nums[l] == lv) l++; // 左去重 while (l < r && nums[r] == rv) r--; // 右去重 } else if (sum < target) { l++; } else { r--; } } return ans; } // 简单自测 public static void main(String[] args) { int[] a = {1, 1, 2, 2, 3, 4, 4, -1, 5}; System.out.println(twoSumAllUnique(a, 5)); // [[1,4], [2,3], [-1,6] 如果6存在就会列出] } } ``` ## 思路 B:哈希 + 自定义 Pair(用 equals/hashCode 去重) * 扫描数组,用 `seen` 记录出现过的数; * 遇到 `x`,若 `target-x` 在 `seen` 中,得到一对 `(min(x, y), max(x, y))`; * 用 `Set<Pair>` 存对;`Pair` 的 `equals/hashCode` 只比较 `a` 和 `b`(且约定 `a<=b`),即可去重。 * 复杂度:时间 `O(n)`,空间 `O(n)`。 ### 代码(含 equals/hashCode) ```java import java.util.*; public class TwoSumHashSet { static class Pair { final int a, b; // 约定 a <= b Pair(int x, int y) { this.a = Math.min(x,y); this.b = Math.max(x,y); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Pair)) return false; Pair p = (Pair) o; return a == p.a && b == p.b; } @Override public int hashCode() { return Objects.hash(a, b); } @Override public String toString() { return "[" + a + ", " + b + "]"; } } public static Set<Pair> twoSumAllUnique(int[] nums, int target) { Set<Integer> seen = new HashSet<>(); Set<Pair> ans = new LinkedHashSet<>(); for (int x : nums) { int y = target - x; if (seen.contains(y)) ans.add(new Pair(x, y)); seen.add(x); } return ans; } public static void main(String[] args) { int[] a = {1,1,2,2,3,4,4,-1,5}; System.out.println(twoSumAllUnique(a, 5)); // 如: [[1,4], [2,3]] } } ``` ### 补充:按“指定字段”判相等(独立示例) > 假设只按 `id+name` 判两个用户是否相同,忽略其他字段: ```java class User { long id; String name; String mobile; String email; @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User)) return false; User u = (User) o; return id == u.id && Objects.equals(name, u.name); } @Override public int hashCode() { return Objects.hash(id, name); } } ```
    发布于 2025-08-14 20:22 •IP属地 辽宁
    举报
    评论
    收藏