HackerRank Gemstones问题Java解法无法通过最后一个测试用例如何解决
问题原因
你的代码逻辑本身在岩石数量大于0的场景下是完全正确的,无法通过第30个测试用例大概率是以下两个原因:
- 边界条件缺失:如果测试用例输入的岩石数量为0(即空列表),你的代码会判定所有26个字母都满足「出现次数等于岩石数量」,返回26,但实际预期结果为0。
- 输入读取不严谨:主方法中读取每块岩石的矿物字符串时没有做
trim()处理,若平台测试用例的输入行带有首尾空白字符,极端场景下如果某行全是空白,会导致不符合题目输入约定的字符串进入逻辑。
修复方案
你可以直接修改gemstones方法,增加空列表判断,同时可以去掉没必要的List转数组步骤,优化后代码如下:
public static int gemstones(List<String> arr) { // 增加空列表边界判断 if(arr == null || arr.isEmpty()) { return 0; } int count[]=new int[26]; // 直接遍历List无需转数组 for(String rock : arr){ for(int j=0;j<26;j++){ char c=(char)(j+'a'); if(rock.indexOf(c)!=-1) { count[j]++; } } } int gemCount = 0; for(int i=0;i<26;i++){ if(count[i]==arr.size()) { gemCount++; } } return gemCount; }
如果需要更简洁高效的实现,也可以用位运算方案,每个岩石用int低26位标记存在的字符,所有岩石的标记值做按位与运算,最后统计结果中1的个数即可:
public static int gemstones(List<String> arr) { if(arr == null || arr.isEmpty()) return 0; int mask = (1<<26) -1; for(String rock : arr) { int rockMask = 0; for(char c : rock.toCharArray()) { rockMask |= 1 << (c-'a'); } mask &= rockMask; // 提前退出:已经没有公共字符了 if(mask == 0) break; } return Integer.bitCount(mask); }
另外可以把主方法中读取岩石字符串的代码加上trim(),进一步避免输入问题:
return bufferedReader.readLine().trim();
内容的提问来源于stack exchange,提问作者Raghav Upadhyay
相关产品推荐
相关产品推荐

