去重并输出乘积相同的不重复整数对的Java实现疑问
数组中乘积相同的不重复整数对解决方案及内存效率分析
嘿,我明白你的需求:输入一组无重复整数,找出所有乘积相等的整数对,而且得避免重复输出(比如40×1和1×40算同一对),同时你还关心实现的内存效率对吧?
先聊聊常见实现的问题:如果用最直接的双重循环暴力枚举,虽然内存占用低,但时间复杂度是O(n²),还得额外处理重复配对,反而可能增加不必要的内存开销。我给你优化了一个基于哈希表的实现,既解决了重复配对问题,又能精准控制内存使用:
优化后的完整代码
import java.util.*; public class ProductPairFinder { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入无重复整数数组(用空格分隔):"); String[] inputStr = sc.nextLine().split(" "); int[] nums = new int[inputStr.length]; for (int i = 0; i < inputStr.length; i++) { nums[i] = Integer.parseInt(inputStr[i]); } sc.close(); // 哈希表:key是乘积值,value是该乘积对应的不重复数对集合 Map<Integer, Set<List<Integer>>> productToPairs = new HashMap<>(); // 用字符串标识已经处理过的数对,防止重复添加(比如(a,b)和(b,a)) Set<String> processedPairKeys = new HashSet<>(); // 只遍历i<j的情况,直接避免反向配对 for (int i = 0; i < nums.length; i++) { for (int j = i + 1; j < nums.length; j++) { int product = nums[i] * nums[j]; List<Integer> currentPair = Arrays.asList(nums[i], nums[j]); // 生成唯一的数对标识,确保(a,b)和(b,a)对应同一个key String pairKey = nums[i] < nums[j] ? nums[i] + ":" + nums[j] : nums[j] + ":" + nums[i]; if (!processedPairKeys.contains(pairKey)) { processedPairKeys.add(pairKey); // 不存在该乘积时自动创建空集合,再添加数对 productToPairs.computeIfAbsent(product, k -> new HashSet<>()).add(currentPair); } } } // 输出结果:只打印有多个数对的乘积组 System.out.println("乘积相同的整数对结果:"); for (Map.Entry<Integer, Set<List<Integer>>> entry : productToPairs.entrySet()) { if (entry.getValue().size() > 1) { System.out.printf("乘积为%d的数对:%s%n", entry.getKey(), entry.getValue()); } } } }
内存效率详解
- 从源头减少冗余:循环中让
j从i+1开始,直接只生成正向的数对,完全避免了(a,b)和(b,a)这种重复配对的生成,相比暴力遍历所有i和j(包括i>j),内存中少存了一半的临时对象。 - 哈希表的精准存储:
productToPairs只存储那些有多个数对的乘积(最终输出时筛选掉只有单个对的情况),不会浪费内存存储无用的单一对数据;processedPairKeys用简短的字符串作为键,比存储完整的列表对象占用的内存小得多。 - 临时对象可控:遍历过程中生成的
currentPair是临时对象,但只有符合条件的才会被存入集合,不会产生大量冗余的对象实例。
额外优化建议
如果你的数组规模特别大(比如上万级别的元素),可以先对数组进行排序,然后结合哈希表来进一步减少内存占用——排序后可以更方便地生成唯一的数对标识,甚至可以跳过一些不可能形成乘积重复的元素组合,但对于大多数常规场景,上面的实现已经足够高效且内存友好了。
内容的提问来源于stack exchange,提问作者Redent
相关产品推荐
相关产品推荐

