字节笔试
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);
}
}
