【华为OD题库-068】找出经过特定点的路径长度-java
题目
输入一个字符串,都是以大写字母组成,每个相邻的距离是1,第二行输入一个字符串,表示必过的点。
说明
每个点可过多次。求解经过这些必过点的最小距离是多少?
示例1
输入输出示例仅供调试,后台判题数据一般不包含示例
输入
ANTSEDXQOKPUVGIFWHJLYMCRZB
ABC
输出
28
思路
本题不好理解,以示例数据为例,要经过ABC,必须走的路径是A->B->C,其中A->B的距离为25,b->c的距离为3,所以最后结果为28
题目描述太过简略,本文按照以下细节实现:
- 第一行和第二行均有可能含重复字符串
- 出发点并非起点
- 运动方向可随意变更,不能重复走原点。比如第二行输入ABBG,已经在第一个B了,需要找下一个B,而非自己
穷举所有可能性的组合,然后计算最短距离即可
题解
package hwod;
import java.util.*;
public class CrossSpecDotPath {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String targetStr = sc.nextLine();
System.out.println(crossSpecDotPath(str1, targetStr));
}
private static Map<Character, List<Integer>> map = new HashMap<>(); //存放每个字符所有的索引位置
private static int res = Integer.MAX_VALUE;
private static int crossSpecDotPath(String originStr, String targetStr) {
for (int i = 0; i < originStr.length(); i++) {
List<Integer> oldList = map.getOrDefault(originStr.charAt(i), new ArrayList<>());
oldList.add(i);
map.put(originStr.charAt(i), oldList);
}
LinkedList<Integer> path = new LinkedList<>();//存放选择的路径
dfs(path, targetStr, 0);
return res;
}
private static void dfs(LinkedList<Integer> path, String targetStr, int distance) {
if (targetStr.length() < 1) {//路径走完了
if (distance < res) {
res = distance;
}
return;
}
List<Integer> list = map.get(targetStr.charAt(0));//本次寻找的目标字符,可能出现在哪些位置
for (int item : list) {
if (!path.isEmpty() && path.peekLast() == item) continue;//不允许走原点
if (!path.isEmpty()) distance += Math.abs(item - path.peekLast());//累加距离
path.addLast(item);
dfs(path, targetStr.substring(1), distance);//找下一个目标
int lst = path.peekLast();
path.removeLast();
if (!path.isEmpty()) distance -= Math.abs(lst - path.peekLast());
}
}
}
推荐
如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。