CodeSignal Arcade第4-16题Are Similar?代码隐藏用例失败求助
CodeSignal Arcade第4-16题「Are Similar?」代码错误排查
我通过了该题所有可见测试用例,但隐藏用例全部失败,无法定位问题,代码及题目信息如下:
题目说明
若两个数组可通过交换其中一个数组中至多一对元素得到彼此,则称这两个数组相似。给定两个数组,判断它们是否相似。
示例
- 当A = [1, 2, 3],B = [1, 2, 3]时,输出
areSimilar(A, B) = true(数组相等,无需交换); - 当A = [1, 2, 3],B = [2, 1, 3]时,输出
areSimilar(A, B) = true(交换A中2和1可得到B); - 当A = [1, 2, 2],B = [2, 1, 1]时,输出
areSimilar(A, B) = false(无法通过至多一次交换使两数组相等)。
约束条件
b.length = a.length
我的代码
boolean solution(int[] a, int[] b) { int count = 0; ArrayList<Integer> tempa = new ArrayList<>(); ArrayList<Integer> tempb = new ArrayList<>(); for(int i = 0; i < a.length; i++){ if(a[i]!=b[i]){ count++; tempa.add(a[i]); tempb.add(b[i]); } } if(count==0||(count==2 && tempa.get(0)==tempb.get(1) && tempa.get(1)==tempb.get(0))) return true; else return false; }
已通过的测试用例
- a: [1, 2, 3],b: [1, 2, 3]
- a: [1, 2, 3],b: [2, 1, 3]
- a: [1, 2, 2],b: [2, 1, 1]
- a: [1, 2, 1, 2],b: [2, 2, 1, 1]
- a: [1, 2, 1, 2, 2, 1],b: [2, 2, 1, 1, 2, 1]
- a: [1, 1, 4],b: [1, 2, 3]
- a: [1, 2, 3],b: [1, 10, 2]
- a: [2, 3, 1],b: [1, 3, 2]
- a: [2, 3, 9],b: [10, 3, 2]
- a: [832, 998, 148, 570, 533, 561, 894, 147, 455, 279],b: [832, 570, 148, 998, 533, 561, 455, 147, 894, 279]
错误原因及修复
核心问题
代码中用==比较ArrayList<Integer>中的元素时,实际比较的是Integer对象的引用,而非数值本身。
Java对-128~127范围内的Integer值会缓存,此时==能正确比较数值;但数值超出该范围时,每次创建的Integer都是新对象,==比较引用会返回false,导致符合条件的测试用例被误判。
比如测试用例a: [128, 129],b: [129, 128],逻辑上应返回true,但代码中tempa.get(0)==tempb.get(1)会因引用不同返回false,最终输出错误结果。
修复后的代码
方案1:改用equals()比较Integer值
boolean solution(int[] a, int[] b) { int count = 0; ArrayList<Integer> tempa = new ArrayList<>(); ArrayList<Integer> tempb = new ArrayList<>(); for(int i = 0; i < a.length; i++){ if(a[i]!=b[i]){ count++; tempa.add(a[i]); tempb.add(b[i]); } } if(count==0 || (count==2 && tempa.get(0).equals(tempb.get(1)) && tempa.get(1).equals(tempb.get(0)))) return true; else return false; }
方案2:用int数组存储差异元素(更高效)
直接使用int类型比较,完全避免对象引用问题,还能在差异数超过2时提前终止循环:
boolean solution(int[] a, int[] b) { int count = 0; int[] diffA = new int[2]; int[] diffB = new int[2]; for(int i = 0; i < a.length; i++){ if(a[i]!=b[i]){ if(count >= 2) return false; // 差异数超过2,直接返回false diffA[count] = a[i]; diffB[count] = b[i]; count++; } } return count == 0 || (count == 2 && diffA[0] == diffB[1] && diffA[1] == diffB[0]); }
内容的提问来源于stack exchange,提问作者roger
相关产品推荐
相关产品推荐

