字节笔试
public class 循环依赖 { /** 本质上就是拓扑排序问题 * 在完成A之前需要先完成B,B之前需要C以此类推 * 点的范围[1,9] * 此题不难拓扑排序的板板,搞懂输入就行 * 输入 * 第一行 t 表示一共有t行数据 * 第二行 一列数[1,9] 表示 询问他们能否完成 * 接下来每行代表依赖关系 * 每一行 第一个数x 后面的数都是x的依赖 a b c.... (在完成x之前必须完成它所依赖的那些) */ public static void main(String[] args) { ArrayList<Integer> query = new ArrayList<>(); Scanner sc = new Scanner(System.in); int t = sc.nextInt() - 1; sc.nextLine(); String[] s = sc.nextLine().split(" "); for (String x : s) { query.add(Integer.parseInt(x)); } List<Integer>[] g = new ArrayList[10]; Arrays.setAll(g, k -> new ArrayList<>(10)); int[] degree = new int[10]; Arrays.fill(degree, -1); for (int k = 0; k < t; k++) { String[] nums = sc.nextLine().split(" "); int x = 0, y; for (int i = 0; i < nums.length; i++) { if (i == 0) { x = Integer.parseInt(nums[i]); } else { y = Integer.parseInt(nums[i]); g[y].add(x); if (degree[y] == -1) { degree[y] = 0; } if (degree[x] == -1) { degree[x] = 1; } else { degree[x]++; } } } } ArrayDeque<Integer> q = new ArrayDeque<>(); for (int i = 1; i < degree.length; i++) { if (degree[i] == 0) q.offer(i); } while (!q.isEmpty()) { int y = q.poll(); for (int x : g[y]) { degree[x]--; if (degree[x] == 0) q.offer(x); } } for (int u : query) { // 可以完成入度为0 输出1,完不成就输出0 int res = degree[u] == 0 ? 1 : 0; System.out.print(res + " "); } } }
public class 最大乘积子数组 { /** 值得注意的点:直接保存乘积会爆long,可以把2^10以内的预存这样就可以O(1)得到一个数是2的多少次幂 * 数组nums 索引从1开始 * nums[i] 属于 {0,1,2,4,8,16,32,64,....,1024} * 求乘积最大的子数组的区间 * 有多行测试集 * 输入描述 * 第一行输入t表示有t个测试用例 * 每个测试用例由2行组成 * * 第1个用例: * 第一行 数组长度n * 第二行 数组 * 第2个用例: * 第一行 n * 第二行 数组 */ static int[] map = new int[1025]; static { for (int i = 0; i <= 10; i++) { map[1 << i] = i; } } static int N = (int) 1e4; static int[] nums = new int[N + 1]; public static void main(String[] args) { // write your code here Scanner sc = new Scanner(System.in); int t = sc.nextInt(); for (int k = 0; k < t; k++) { int n = sc.nextInt(); int cru = 0; int max = 0; int x = 1, y = 1; for (int i = 1, j = 1; i <= n; i++) { nums[i] = sc.nextInt(); if (nums[i] != 0) { cru += map[nums[i]]; } else { j = i + 1; cru = 0; } if (cru > max) { x = j; y = i; max = cru; } } System.out.printf("%d %d", x, y); System.out.println(); } } }
这题当时没想出来考完补的
public class 翻转子数组后的最大子段和 { static long MIN = -(Long.MAX_VALUE >> 20); public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] nums = new int[n]; for (int i = 0; i < nums.length; i++) { nums[i] = sc.nextInt(); } // 以k结尾的最大字段和 + 后半段的最大后缀和 // 多余的部分可以认为通过翻转被删掉 // nums[0~k~n-1] // 0 1 2 ... l...k....r r+1 ..... n-1 // k+1~r可以认为被删除了 r+1~n-1重新续上sum[k] // dp[j]表示从右开始的最大后缀和 // 复杂度分析 // 找前半段是的字段和 O(N) + 后半段以O(1)找到最大后缀 // 总复杂度O(N) long[] dp = new long[n + 1]; long sum = 0, max = MIN; dp[n] = MIN; for (int j = n - 1; j >= 0; j--) { sum += nums[j]; dp[j] = Math.max(sum, dp[j + 1]); } sum = 0; long res = MIN; dp[n] = 0; for (int i = 0; i < n; i++) { // fixed 修复最大子段和 sum = Math.max(sum + nums[i], nums[i]); max = Math.max(max, sum); res = Math.max(res, max + dp[i + 1]); } System.out.println(res); } }
public class 长为k的子数组最大和 { /** * 可以在n个元素的数组中去掉一个元素 * 求长为k的子数组的最大和 * 输入: * 5 3 * 2 1 3 -1 4 * 输出: * 8 * 解释:去掉-1后 {1, 3, 4}组成k=3的子数组和最大 8 */ public static void main(String[] args) { // 基本思路就是滑动窗口+单调队列 // 单调队列维护窗口 最小值的索引 // 淘汰最小值之后 找到窗口两端相邻的元素补进来 Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); int[] nums = new int[n]; for (int i = 0; i < nums.length; i++) { nums[i] = sc.nextInt(); } ArrayDeque<Integer> q = new ArrayDeque<>(k + 1); int sum = 0; int res = 0; for (int i = 0; i < nums.length; i++) { // 窗口现成 左端滑出 sum减掉 if (i >= k) { sum -= nums[i - k]; } sum += nums[i]; while (!q.isEmpty() && nums[i] <= nums[q.peekLast()]) q.removeLast(); q.offer(i); // 如果对头已经滑出窗口 淘汰 if (!q.isEmpty() && i - q.peekFirst() + 1 > k) { q.removeFirst(); } // 形成了k大小的窗口 if (i >= k - 1) { int x, y = 0, z = 0; assert !q.isEmpty(); x = nums[q.peekFirst()]; if (i + 1 < nums.length) { y = nums[i + 1]; } if (i >= k) z = nums[i - k]; // 把窗口内最小元素淘汰 用相邻更大价值的补回来 不然相当于当前窗口不删除元素就已经最大 res = sum - x + Math.max(Math.max(x, y), z); } } System.out.println(res); } }