Java中用HashMap+异或判断矩形合法性的问题排查
矩形边长判断逻辑的问题排查
给定四个边长a、b、c、d,判断是否能构成矩形,能则返回1,否则返回0。我用HashMap和异或操作实现逻辑,但测试用例a=2、b=3、c=2、d=2执行失败,想确认解法是否有问题。代码如下:
HashMap<Integer, Integer> hm = new HashMap<>(); int [] numbers = {A,B,C,D}; for(int i=0;i<numbers.length;i++) { hm.putIfAbsent(numbers[i],hm.getOrDefault(numbers[i],0)+1); } int res = 0; for(int val : hm.values()) { res = res ^ val; } if(hm.size() == 2 && res == 0) { return 1; } return 0;
问题根源
你的代码有两个关键错误:
- 计数逻辑彻底错误:
putIfAbsent仅在键不存在时才赋值,遇到重复元素时不会更新计数。比如测试用例里的三个2,第一次存入时计数为1,后面两次遇到2时,因为键已存在,putIfAbsent直接跳过,最终统计结果是2出现1次、3出现1次——这完全不符合实际次数,导致后续判断逻辑完全失效。 - 异或判断的逻辑不严谨:矩形的合法情况只有两种:要么是两组各两个相同的边长(普通矩形),要么是四个边长完全相同(正方形,属于特殊矩形)。你的判断条件只覆盖了
size=2且异或为0的情况,但异或为0的组合不止“2和2”——比如“1和3”异或结果也是0,而这种计数对应的是一个数出现1次、另一个出现3次,根本无法构成矩形。加上前面计数逻辑的错误,才会导致测试用例误判为可以构成矩形。
修正方案
方案一:修复计数逻辑+精准判断
先把计数逻辑改对,然后针对两种合法情况明确判断:
HashMap<Integer, Integer> hm = new HashMap<>(); int[] numbers = {A, B, C, D}; for (int num : numbers) { // 用put替代putIfAbsent,确保每次都更新计数 hm.put(num, hm.getOrDefault(num, 0) + 1); } // 合法情况:要么两组各2个,要么4个全相同 if ((hm.size() == 2 && hm.values().stream().allMatch(count -> count == 2)) || (hm.size() == 1 && hm.values().iterator().next() == 4)) { return 1; } return 0;
方案二:异或结合计数(更简洁高效)
利用异或特性:合法矩形的四个边长异或结果一定是0(a^a^b^b=0,a^a^a^a=0),但异或为0不代表合法(比如1、2、3、0的异或也是0,但无法构成矩形),所以需要结合计数判断:
int xor = A ^ B ^ C ^ D; HashMap<Integer, Integer> hm = new HashMap<>(); int[] numbers = {A, B, C, D}; for (int num : numbers) { hm.put(num, hm.getOrDefault(num, 0) + 1); } // 异或为0,且要么只有1种边长(4次),要么2种边长各2次 if (xor == 0 && (hm.size() == 1 || hm.size() == 2)) { return 1; } return 0;
内容的提问来源于stack exchange,提问作者Koushik Andhavarapu
相关产品推荐
相关产品推荐

