# 2022校招：华为笔试

17 篇文章 2 订阅

1. 最大绝对值之差
树。找出一个节点，把这个节点与parent隔断，成为新的树的root。目标是最大化两颗树的差值。返回应该割裂开的节点，如果出现平局，返回索引较小的。
第一行输入是n，表示一共多少节点。第二行是所有节点的值。之后是节点的关系，【parent，child】。

input:
4
4 9 -7 -8
0 1
0 3
1 2

output: 3

public class Main {
static int largestGap = 0;
static int res = 100000;

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
Node[] nodes = new Node[n];
boolean[] notRoot = new boolean[n];
for (int i = 0; i < n; i++) {
int v = sc.nextInt();
nodes[i] = new Node(i, v);
}
while (sc.hasNextInt()) {
int p = sc.nextInt();
int c = sc.nextInt();
Node par = nodes[p];
Node child = nodes[c];
notRoot[c] = true;
if (par.left == null)
par.left = child;
else
par.right = child;
}
Node root = null;
for (int i = 0; i < n; i++) {
if (!notRoot[i]) {
root = nodes[i];
break;
}
}
subtreeSum(root);
findGap(root, 0);
System.out.println(res);
}

private static void findGap(Node root, int parVal) {
if (root == null)
return;
int left = 0;
int right = 0;
//        System.out.printf("findgap(), root.id=%d, largestGap=%d, res=%d\n", root.idx, largestGap,
//                        res);
if (root.left != null) {
left = root.left.sum;
int leftgap = Math.abs(root.sum + parVal - 2 * left);
//            System.out.printf("left=%d, leftgap=%d\n", left, leftgap);
if (leftgap > largestGap) {
largestGap = leftgap;
res = root.left.idx;
} else if (leftgap == largestGap && root.left.idx < res) {
res = root.left.idx;
}
}
if (root.right != null) {
right = root.right.sum;
int rightgap = Math.abs(root.sum + parVal - 2 * right);
//            System.out.printf("right=%d, rightgap=%d\n", right, rightgap);
if (rightgap > largestGap) {
largestGap = rightgap;
res = root.right.idx;
} else if (rightgap == largestGap && root.right.idx < res) {
res = root.right.idx;
}
}
//        System.out.printf("largestGap=%d, res=%d\n", largestGap, res);
findGap(root.left, parVal + root.val + right);
findGap(root.right, parVal + root.val + left);
}

private static int subtreeSum(Node root) {
if (root == null)
return 0;
int left = subtreeSum(root.left);
int right = subtreeSum(root.right);
int s = left + right + root.val;
root.sum = s;
return s;
}
}

class Node {
int idx;
int val;
int sum;
Node left;
Node right;

public Node(int i, int v) {
idx = i;
val = v;
sum = 0;
left = null;
right = null;
}
}

1. 梅花桩
格子表示可跳跃的步数。第一行是m,n，表示棋盘的大小。求到达最右下角最少的步数。如果无法到达，返回-1。
public class Main {

public static void main(String[] args) {
final int INF = 100*100*10+1;
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(",");
int m = Integer.parseInt(input[0]);
if (m <= 0) {
System.out.println("-1");
return;
}
int n = Integer.parseInt(input[1]);
if (n <= 0) {
System.out.println("-1");
return;
}
int[][] grid = new int[m][n];
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
grid[i][j] = sc.nextInt();
dp[i][j] = INF;
}
}
dp[0][0] = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) continue;
for (int k = 1; k <= grid[i][j]; k++) {
if (j+k >= n) break;
if (grid[i][j+k] == 0) continue;
dp[i][j+k] = Math.min(dp[i][j+k], dp[i][j]+1);
}
for (int k = 1; k <= grid[i][j]; k++) {
if (i+k >= m) break;
if (grid[i+k][j] == 0) continue;
dp[i+k][j] = Math.min(dp[i+k][j], dp[i][j]+1);
}
}
}
if (dp[m-1][n-1] >= INF) {
System.out.println("-1");
return;
}
System.out.println(dp[m-1][n-1]);
}

private static void print2d(int[][] arr) {
int m = arr.length;
for (int i = 0; i < m; i++)
System.out.println(Arrays.toString(arr[i]));
System.out.println();
}
}

1. 最短编译时间
只过5%的test case，时间来不及。
不同项目需要不同的依赖。第一行是目标项目。之后每一行表示一个项目所依赖的项目和编译时间，格式为[项目名称，编译时间，*依赖项目]。依赖的项目必须要先做完。
input:
module3
module1,10
module2,5
module3,10,module1,module2

output: 20

input:
module2
module2,10,module1

output: -1

input:
module2
module2,10,module1
module1,10,module2

output: -1

public class Main {
static boolean valid = true;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String goal = sc.nextLine().trim();
Map<String, Integer> duration = new HashMap();
Map<String, Set<String>> prereqs = new HashMap();
while (sc.hasNextLine()) {
String[] input = sc.nextLine().split(",");
int d = Integer.parseInt(input[1]);
duration.put(input[0], d);
Set<String> pre = new HashSet();
for (int i = 2; i < input.length; i++)
prereqs.put(input[0], pre);
}
int res = getTime(goal, duration, prereqs, new HashSet());
if (!valid)
System.out.println("-1");
else
System.out.println(res);
}

private static int getTime(String cur, Map<String, Integer> duration, Map<String, Set<String>> prereqs, Set<String> seen) {
if (!valid) return -1;
if (!prereqs.containsKey(cur) || seen.contains(cur)) {
valid = false;
return -1;
}
Set<String> pres = prereqs.get(cur);
int t = duration.get(cur);
int front = 0;
for (String pre: pres) {
front = Math.max(front, getTime(pre, duration, prereqs, seen));
}
// 这行是考完之后才加的，忘记backtrack
seen.remove(cur);
return t+front;
}
}


• 0
点赞
• 0
评论
• 2
收藏
• 一键三连
• 扫一扫，分享海报

05-24

08-21
09-29 1025
08-17 2万+
11-25 9409
03-08 1万+
11-10
05-29
03-20
09-22 74
11-05 3878
07-07 3282
08-22