找出经过特定点的路径长度
题目描述
无
输入描述
输入一个字符串,都是以大写字母组成,每个相邻的距离是 1,
第二行输入一个字符串,表示必过的点。
说明每个点可过多次。
输出描述
经过这些必过点的最小距离是多少
用例
输入 | ANTSEDXQOKPUVGIFWHJLYMCRZB |
输出 | 28 |
说明 | 无 |
源码和解析
解析:
这个题重在理解,可以使用动态规划DP算法进行求解。
在用例
ANTSEDXQOKPUVGIFWHJLYMCRZB
ABC
中 A->0 B-25 C-22 那么从起点字符串开始的起点A -> 目标点A距离为0 A到B距离为25-0=25 B-C= |25-22|=3 那么ABC的最小距离为28
倘若字符串中包含多个A或者多个B的情况
那么{A:[ 1,3,5…],B:[4,6,8],C:[12,13]}
==》ABC 为三个列表的有序组合 [1,4,12] 距离为 (1-0)+(4-1)+(12-4)
==》ABBC 则为四个列表的有序组合
因此可以使用动态规划算法进行求解,不懂的可以到我的个人主页去算法专栏查找。
示例代码:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class T42 {
static int num[] = null;// 记录 每次dfs产生的 临时数据
static String objInput = "";
static int min = -1;// 最小路径距离
static Map<Character, List<Integer>> map = null;
public static void main(String[] args) {
String input = "ANTBSEDXQOKPUAVGIFWHJLYMCRZB";
objInput = "ABCB";
map = new HashMap<Character, List<Integer>>();
for (int i = 0; i < objInput.length(); i++) {
if (!map.containsKey(objInput.charAt(i))) {
map.put(objInput.charAt(i), new ArrayList<Integer>());
}
for (int j = 0; j < input.length(); j++) {
if (input.charAt(j) == objInput.charAt(i)) {
if (map.get(input.charAt(j)).contains(j))
continue;
map.get(input.charAt(j)).add(j);
}
}
}
System.out.println(map);
num = new int[objInput.length()];
dfs(0);
System.out.println(min);
}
/**
*
* @param p
* 位置序号 从0开始 通过该序号 可以取到键及其对应的列表
*/
public static void dfs(int p) {
if (p >= objInput.length()) {
int tempDistance = num[0];//
// System.out.print(num[0]+" ");
for (int i = 1; i < num.length; i++) {
tempDistance += Math.abs(num[i] - num[i - 1]);
// System.out.print(num[i]+" ");
}
// System.out.println();
if (min == -1) {
min = tempDistance;
}
if (tempDistance < min) {
min = tempDistance;
}
return;
}
for (int i = 0; p < num.length
&& i < map.get(objInput.charAt(p)).size(); i++) {
num[p] = map.get(objInput.charAt(p)).get(i);
dfs(p + 1);
}
}
}
代码运行示意图: