1. 求字符串排列组合
获取字符串无重复排列组合数量。
输入:
baac
输出:
12
分析:
- 要考虑到字符串有重复的字母
- 字符数量阶乘 / 每一个字母数量阶乘
- 使用 map 记录每一个字符的 count。
代码:
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class StringPermutations { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { StringPermutations sp = new StringPermutations(); sp.str = scanner.next(); int res = sp.permutation(); System.out.println(res); } } public String str; public int permutation() { if(str.isEmpty()) return 0; int len = str.length(); char[] arr = str.toCharArray(); Map<Character, Integer> map = new HashMap<>(); int count = getFactorial(len); for(int i = 0; i < len; i++) { int c = map.containsKey(arr[i]) ? map.get(arr[i]) + 1 : 1; map.put(arr[i], c); } int div = 1; for(Character c : map.keySet()) { div *= getFactorial(map.get(c)); } return count/div; } public int getFactorial(int num) { int res = 1; for(int i = 1; i <= num; i++) { res *= i; } return res; } }
2. 删除字母求字典序最小的字符串
删除字母求字典序最小的字符串。输入 第一行代表字符串,第二行 k 代表要删除字母的个数,k 小于字符串长度。输出字典序最小的字符串。
输入:
abacc
1
输出:
aacc
分析:
贪心算法,每一次都从前往后删除,当遇到第一个比后面字符大的字符,删掉当前的字符。停止
循环删除 k 次
代码:
import java.util.Scanner; public class MinDictionary { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { MinDictionary md = new MinDictionary(); md.str = scanner.next(); md.k = scanner.nextInt(); String res = md.getAnswer(); System.out.println(res); } } private String str; private int k; public String getAnswer() { String res = str; for(int i = 0; i < k; i++) { res = core(res); } return res; } public String core(String str) { char[] arr = str.toCharArray(); StringBuilder sb = new StringBuilder(); boolean flag = true; for(int i = 1; i < arr.length; i++) { if(!flag) { sb.append(arr[i]); } else { if(arr[i] < arr[i-1]) { flag = false; sb.append(arr[i]); } else { sb.append(arr[i-1]); } } } return sb.toString(); } }
3. 约会城市最短路径 + 有限路费
题目大意:
k : 硬币数量
n:城市数量
r:城市道路数量
接下来输入 r 行,每一行有四个元素,第一个表示源城市 S,第二个表示目标城市 D , 第三个表示路径长度 L,第四个表示路费 C
求从 1 ~ n 的最短路径,并且能保证硬币足够。如果没有这样的路径那么输出 -1;
分析:
遍历所有道路,如果源城市与当前城市相同,那么就进行一次判定。
减去路费,目标城市变为源城市,路径长度变长。
递归下去
输入:
5
6
7
1 2 2 4
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2
输出:
11
代码:
import java.util.Scanner; public class MinDistanceWithLimitedCoins { public static void main(String[] args) { // test(); Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { MinDistanceWithLimitedCoins md = new MinDistanceWithLimitedCoins(); md.K = scanner.nextInt(); md.N = scanner.nextInt(); md.R = scanner.nextInt(); road = new int[md.R][4]; for(int i = 0; i < md.R; i++) { for(int j = 0; j < 4; j++) { road[i][j] = scanner.nextInt(); } } int res = md.getAnswer(0, 1, md.K); System.out.println(res); } } private int K = 5; private int N = 6; private int R = 7; private static int[][] road; public int getAnswer(int L, int curCity, int K) { int min = Integer.MAX_VALUE; if(curCity == N) { return L; } else { for(int i = 0; i < R; i++) { if(road[i][0] == curCity && road[i][3] <= K) { int tmp = getAnswer(L + road[i][2], road[i][1], K - road[i][3]); min = tmp == -1 ? min : Math.min(tmp, min); } } } return min == Integer.MAX_VALUE ? -1 : min; } public static void test() { MinDistanceWithLimitedCoins md = new MinDistanceWithLimitedCoins(); road = new int[][]{{1, 2, 2, 4}, {2, 4, 3, 3}, {3, 4, 2, 4}, {1, 3, 4, 1}, {4, 6, 2, 1}, {3, 5, 2, 0}, {5, 4, 3, 2}}; int res = md.getAnswer(0, 1, md.K); System.out.println(res); } }
全部评论
(5) 回帖