3.10深信服笔试
1.字符不重复的最小次数
题意
给你一个长度为N的字符串,你可以删除任意位置的字符,删除后,该字符的左右字符会成为新的邻居,问需要删除多少个字符,可以是的每个字符的邻居不相同。
思路
比较简单的写法是用栈模拟,从前往后依次将字符加入栈中,如果和栈顶元素不相同,则入栈。相同则出栈。
代码
import java.util.Scanner; public class A { static int maxn = 50 + 10; //数据范围 static char[] stack = new char[maxn]; static char[] chars; static int t; static int n; /*栈模拟*/ public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); sc.nextLine(); chars = sc.nextLine().toCharArray(); int ans=0; for (int i = 0; i < chars.length; i++) { while (t > 0 && stack[t - 1] == chars[i]) { --t; ans++; } stack[t++]=chars[i]; } System.out.println(ans); } }
2.网络是否连通
题意
先给你一堆Ip,和IP对应的序号。再给你序号与序号之间的连接关系。最后有q次询问,每次询问两个IP是否连通。
思路
很裸的并查集,套模板就行。
代码
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class B { /** * 并查集模板 * @param args */ static Map<String, String> set = new HashMap<>(); static String[] arr; static int n, m; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); m = sc.nextInt(); arr = new String[n + 1]; for (int i = 1; i <= n; i++) { String ip = sc.next(); set.put(ip, ip); int id = sc.nextInt(); arr[id] = ip; } for (int i = 0; i < m; i++) { int a = sc.nextInt(); int b = sc.nextInt(); union(arr[a],arr[b]); } int q = sc.nextInt(); for (int i = 0; i < q; i++) { System.out.println(isSet(sc.next(),sc.next())?"Yes":"No"); } } public static void union(String a, String b) { String pa = find(a); String pb = find(b); if (pa.equals(pb)) return; set.put(pa, pb); } public static String find(String o) { String p = set.get(o); if (p.equals(o)) return p; p = find(p); set.put(o, p); return p; } public static boolean isSet(String a, String b) { return find(a).equals(find(b)); } }
3.最长连续递减子数组
题意
给你一个数组,求最长的连续递减子数组长度。(ps:不是最长递减子序列)
思路
维护一个当前位置结尾的最长递减子序列长度。如果当前位置比上一个位置小,那么len[i]=len[i-1]+1,否之len[i]=1。len数组可以优化成一个变量。
代码
import java.util.Scanner; public class C { static int maxn = (int) 1e4 + 10; static int n; static int[] arr; public static void main(String[] args) { Scanner sc = new Scanner(System.in); String[] vals = sc.nextLine().split(","); n = vals.length; arr = new int[n + 1]; for (int i = 1; i < arr.length; i++) { arr[i] = Integer.parseInt(vals[i - 1]); } System.out.println(dp()); } public static int dp() { int ans = 0; int pre = 0; arr[0] = Integer.MAX_VALUE; for (int i = 1; i <= n; i++) { pre = arr[i] < arr[i - 1] ? pre + 1 : 1; ans = Math.max(pre, ans); } return ans; } }
4.能拿到的金币数量
题意
给你一个地图g,g[i][j]有三种状态,-1:不可通行。0:可通行,但没钱拿,>0,可通信并且有钱拿。你从[0,0]位置出发,并且你可以使用一次特殊技能,让一个-1的位置变为0。
这题没有AC,以为是走迷宫问题。实际应该是并查集问题,具体做法是,将所有不为-1的块通过并查集连到一块,记录连通块的金币数量。枚举每个不可通行块,得到使其上下左右连通后的价值(这个点需要和[0,0]连通)最后找个最大值。
#深信服求职进展汇总#