1. 解压缩字符串
由内至外还原字符串并替换
1 package Exe1; 2 3 import java.util.Collections; 4 import java.util.Scanner; 5 6 /** 7 * @author zzm 8 * @data 2020/4/10 18:16 9 * 小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩, 10 * 对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么? 11 输入描述: 12 输入第一行包含一个字符串s,代表压缩后的字符串。 13 S的长度<=1000; 14 S仅包含大写字母、[、]、|; 15 解压后的字符串长度不超过100000; 16 压缩递归层数不超过10层; 17 18 输出描述: 19 输出一个字符串,代表解压后的字符串。 20 */ 21 public class Compress { 22 public static void main(String[] args) { 23 Scanner scanner = new Scanner(System.in); 24 String str = scanner.next(); 25 scanner.close(); 26 StringBuilder s = new StringBuilder(str); 27 char c; 28 29 for (int i = 0; i < s.length(); i++) { 30 c = s.charAt(i); 31 if (c == ']') { 32 int left = i, mid; 33 while (s.charAt(--left) != '|') ; 34 mid = left; 35 while (s.charAt(--left) != '[') ; 36 int times = Integer.parseInt(s.substring(left + 1, mid)); 37 String newStr = s.substring(mid + 1, i); 38 newStr = String.join("", Collections.nCopies(times, newStr)); 39 40 s.replace(left,i+1,newStr); 41 i = left; 42 } 43 } 44 System.out.println(s); 45 } 46 }
2. 逛街看楼问题
利用栈缩短时间:
当前楼往左看,比左边楼低则能比处在左边楼多看一座,否则拆(直到左边楼比当前楼高);
当前楼往右看,比右边楼低则能比处在右边楼多看一座,否则拆(直到右边楼比当前楼高)。
package Exe1; import java.util.Scanner; import java.util.Stack; /** * @author zzm * @data 2020/4/10 22:31 * 小Q在周末的时候和他的小伙伴来到大城市逛街,一条步行街上有很多高楼,共有n座高楼排成一行。 * 小Q从第一栋一直走到了最后一栋,小Q从来都没有见到这么多的楼,所以他想知道他在每栋楼的位置处能看到多少栋楼呢? * (当前面的楼的高度大于等于后面的楼时,后面的楼将被挡住) * <p> * 输入第一行将包含一个数字n,代表楼的栋数,接下来的一行将包含n个数字wi(1<=i<=n),代表每一栋楼的高度。 * 1<=n<=100000; * 1<=wi<=100000; * <p> * 输出一行,包含空格分割的n个数字vi,分别代表小Q在第i栋楼时能看到的楼的数量。 */ public class HangStreet { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] nums = new int[n]; for (int i = 0; i < n; i++) nums[i] = scanner.nextInt(); scanner.close(); int totle; Stack<Integer> lefts = new Stack<>(); Stack<Integer> rights = new Stack<>(); int[] a = new int[n]; int[] b = new int[n]; for (int i = 0, j = n - 1; i < n && j >= 0; i++, j--) {
//i位置往左看能看到的楼 a[i] = lefts.size();
//j位置往右看能看到的楼 b[j] = rights.size(); while (!lefts.isEmpty() && lefts.peek() <= nums[i]) lefts.pop(); while (!rights.isEmpty() && rights.peek() <= nums[j]) rights.pop(); lefts.push(nums[i]); rights.push(nums[j]); } for (int i = 0; i < n; i++) { totle = a[i] + b[i] + 1; if (i == n - 1) System.out.print(totle); else System.out.print(totle + " "); } } }
3. 最短假期
package Algorithm; import java.util.Arrays; import java.util.Scanner; import static java.lang.Math.min; /** * @author zzm * @data 2020/4/15 21:48 * 由于业绩优秀,公司给小Q放了 n 天的假,身为工作狂的小Q打算在在假期中工作、锻炼或者休息。 * 他有个奇怪的习惯:不会连续两天工作或锻炼。只有当公司营业时,小Q才能去工作,只有当健身房营业时,小Q才能去健身,小Q一天只能干一件事。 * 给出假期中公司,健身房的营业情况,求小Q最少需要休息几天。 * <p> * 输入描述: * 第一行一个整数 n(1≤n≤100000) 表示放假天数 * 第二行 n 个数 每个数为0或1,第 i 个数表示公司在第 i 天是否营业 * 第三行 n 个数 每个数为0或1,第 i 个数表示健身房在第 i 天是否营业 * (1为营业 0为不营业) * 输出描述: * 一个整数,表示小Q休息的最少天数 */ public class MinRest { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] works = new int[n]; int[] exes = new int[n]; for (int i = 0; i < n; i++) works[i] = scanner.nextInt(); for (int i = 0; i < n; i++) exes[i] = scanner.nextInt(); scanner.close(); //0 for rest, 1 for work, 2 for exe int[][] dp = new int[2][3]; for (int i = 0; i < n; i++) { if (works[i] == 1) dp[1][1] = min(dp[0][0], dp[0][2]); else dp[1][1] = Integer.MAX_VALUE; if (exes[i] == 1) dp[1][2] = min(dp[0][0], dp[0][1]); else dp[1][2] = Integer.MAX_VALUE; dp[1][0] = min(dp[0][0], min(dp[0][1], dp[0][2])) + 1; for (int j = 0; j < 3; j++) dp[0][j] = dp[1][j]; } System.out.println(min(dp[1][0], min(dp[1][1], dp[1][2]))); } }
4. 争夺视野
(此题通过 60%;超时,待改正)
import java.util.Arrays; import java.util.Scanner; /** * @author zzm * @data 2020/4/15 22:30 * 小Q在进行一场竞技游戏,这场游戏的胜负关键就在于能否能争夺一条长度为L的河道,即可以看作是[0,L]的一条数轴。 * 这款竞技游戏当中有n个可以提供视野的道具−真视守卫,第i个真视守卫能够覆盖区间[xi,yi]。现在小Q想知道至少用几个真视守卫就可以覆盖整段河道。 * <p> * 输入描述:输入包括n+1行。 * 第一行包括两个正整数n和L(1<=n<=105,1<=L<=109) * 接下来的n行,每行两个正整数xi,yi(0<=xi<=yi<=109),表示第i个真视守卫覆盖的区间。 * <p> * 输出描述: * 一个整数,表示最少需要的真视守卫数量, 如果无解, 输出-1。 * 示例1 * 输入 * 4 6 * 3 6 * 2 4 * 0 2 * 4 7 * 输出 * 3 */ public class MinEye { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int l = scanner.nextInt(); int[][] eyes = new int[n][2]; for (int i = 0; i < n; i++) { eyes[i][0] = scanner.nextInt(); eyes[i][1] = scanner.nextInt(); } scanner.close(); Arrays.sort(eyes, (a, b) -> a[0] - b[0]); int start = 0, res = 0, index=0; while (start < l) { int temp = start;
//当前视野需要左边<=start 右边大于start, 并找到可覆盖当前最左边视野的 最大右边 for (int i = index; i < n; i++) if (eyes[i][0] <= temp && eyes[i][1] > start) { index = i; start = eyes[i][1]; } if (temp == start) { System.out.println(-1); return; } res++; } System.out.println(res); } }