华为OD机试 2025B卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+E卷+B卷+C卷+D卷)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
给你一个字符串数组 words ,每一个字符串长度都相同,令所有字符串的长度都为 n 。
每个字符串 words[i] 可以被转化为一个长度为n - 1的 差值整数数组 difference[i] ,其中对于 0 <= j <= n - 2 有difference[i][j] = words[i][j+1] - words[i][j]。注意两个字母的差值定义为它们在字母表中 位置 之差,也就是说’a’ 的位置是 0 ,‘b’ 的位置是 1 ,‘z’ 的位置是 25 。
比方说,字符串 “acb” 的差值整数数组是 [2 - 0, 1 - 2] = [2, -1] 。
words 中所有字符串 除了一个字符串以外 ,其他字符串的差值整数数组都相同。你需要找到那个不同的字符串。
请你返回 words中 差值整数数组 不同的字符串。
二、输入描述
第一行输入一个字符串,包含两个数字,空格分隔,数组长度m和数字n,n表示字符串的长度
第二行输入一个字符串,m个长度为n的字符串,空格分隔
例如:
3 3
adc wzy abc
三、输出描述
请返回 words中 差值整数数组不同的字符串。
四、测试用例
测试用例1
1、输入
3 4
abcd bcde cdeg
2、输出
cdeg
3、说明
bcde 和 cdef 的差值数组为 [1, 1, 1],abcf 的为 [1, 1, 3]。
测试用例2
1、输入
4 2
ab cd ef ac
2、输出
ac
3、说明
ab, cd, ef 的差值数组为 [1],ac 的为 [2]。
五、解题思路
1、解题思路
核心思路是为每个输入字符串计算其“差值整数数组”。
然后,统计每种差值数组出现的次数。
根据题目,只有一个字符串的差值数组是独特的,其余 m-1 个字符串的差值数组是相同的。
因此,我们寻找那个只出现过一次的差值数组,并返回对应的原始字符串。
2、具体步骤:
- 计算差值数组 (getDifferenceArray 方法):
- 遍历输入字符串 s 中的每个字符(除了最后一个)。
- 计算 s[j+1] - s[j] 并将结果添加到差值列表 diff 中。
- 字符相减会直接得到它们在ASCII(或Unicode)表中的位置差,这对于英文字母来说等同于它们在字母表中的位置差。
- 填充 diffMap (findUnique 方法):
- 遍历输入的 words 数组中的每个 word。
- 调用 getDifferenceArray(word) 计算其差值数组 diffArray。
- 使用 diffMap.computeIfAbsent(diffArray, k -> new ArrayList<>()).add(word);:
- 这行代码首先检查 diffMap 中是否已存在键 diffArray。
- 如果不存在 (computeIfAbsent 的 lambda k -> new ArrayList<>() 被执行),则创建一个新的空 ArrayList 并将其与 diffArray 关联。
- 然后,将当前的 word 添加到与 diffArray 关联的 List 中。
- 查找独特字符串 (findUnique 方法):
- 遍历 diffMap 中的每一个条目 (Map.Entry)。
- 对于每个条目,检查其值(即 List)的大小。
- 如果 entry.getValue().size() == 1,这意味着这个差值数组模式只对应一个原始字符串,这个字符串就是我们要找的独特字符串。立即返回它。
六、Java算法源码
public class OdTest {
/**
* 计算给定字符串的差值数组。
* @param s 输入字符串
* @return 差值整数列表
*/
public static List<Integer> getDifferenceArray(String s) {
List<Integer> diff = new ArrayList<>();
// 字符串长度至少为2才能计算差值
if (s.length() < 2) {
return diff; // 对于长度小于2的字符串,差值数组为空
}
// 遍历字符串计算相邻字符的差值
for (int i = 0; i < s.length() - 1; i++) {
diff.add(s.charAt(i + 1) - s.charAt(i));
}
return diff;
}
/**
* 从字符串数组中找出具有唯一差值数组的字符串。
* 题目保证了words.length >= 3(或至少存在一个唯一项,如果允许m=2,则会有两个计数为1的项,
* 但题目描述"除了一个字符串以外,其他字符串...都相同"暗示主模式数量为m-1,独特模式数量为1)。
* @param words 字符串数组
* @return 具有唯一差值数组的字符串
*/
public static String findUnique(String[] words) {
if (words == null || words.length == 0) {
return ""; // 处理空或null输入
}
if (words.length == 1) {
return words[0]; // 如果只有一个单词,它本身就是独特的
}
// 使用Map来存储差值数组及其对应的字符串列表
// 键: List<Integer> (差值数组)
// 值: List<String> (所有具有该差值数组的原始字符串)
Map<List<Integer>, List<String>> diffMap = new HashMap<>();
// 遍历每个单词,计算其差值数组,并将其存入Map
for (String word : words) {
List<Integer> diffArray = getDifferenceArray(word);
// computeIfAbsent确保键存在,然后将单词添加到与该差值数组关联的列表中
diffMap.computeIfAbsent(diffArray, k -> new ArrayList<>()).add(word);
}
// 遍历Map,找到其对应字符串列表大小为1的条目
// 这个条目的键就是独特的差值数组,其值列表中的字符串就是我们要找的
for (Map.Entry<List<Integer>, List<String>> entry : diffMap.entrySet()) {
if (entry.getValue().size() == 1) {
return entry.getValue().get(0); // 返回该独特差值数组对应的字符串
}
}
// 根据题目描述,总会找到一个独特的字符串,所以理论上不应到达这里。
// 但为完整性,返回一个空字符串或抛出异常。
return "";
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取数组长度m和字符串长度n
int m = scanner.nextInt();
int n = scanner.nextInt(); // n 在此实现中主要通过 word.length() 获取,但题目有此输入
scanner.nextLine(); // 消耗掉nextInt后余下的换行符
// 读取包含m个字符串的行
String[] words = new String[m];
String lineOfWords = scanner.nextLine();
String[] inputWords = lineOfWords.split(" "); // 按空格分割字符串
// 检查分割后的单词数量是否与m匹配
if (inputWords.length != m) {
// System.err.println("输入单词数量与m不匹配");
// 根据实际情况处理错误,这里简单地取前m个或按实际数量
// 为简单起见,我们假设输入总是正确的
}
for (int i = 0; i < m; i++) {
words[i] = inputWords[i];
}
String result = findUnique(words);
System.out.println(result);
scanner.close();
}
}
七、效果展示
1、输入
3 5
zyxwv vutsr abcde
2、输出
abcde
3、说明
zyxwv 和 vutsr 的差值数组为 [-1, -1, -1, -1],abcde 的为 [1, 1, 1, 1]。
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2025 B卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(A卷+E卷+B卷+C卷+D卷)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。