美团8.13笔试
第一题、int数组,时间t代表送货的平均时间,nums[i]代表订单的最晚截止时间, 问有几个订单不能按时送到。
例:t=5,【5,6,7,8,9,10】,5满足,10满足,答案:4,因为,第二次送货时间是10,所以6,7,8,9不满足。
解答情况:27%,我怀疑我理解错题意了。
思路:模拟
解法:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), t = sc.nextInt();
int[] nums = new int[n];
int res = 0, cnt = 1;
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
if (nums[i] < cnt * t) {
res++;
} else {
cnt++;
}
}
System.out.println(res);
} 第二题、机器人打扫房间。一个int型矩阵,给出一系列指令,可以向上下左右打扫。打扫完成输出Yes和用了几条指令,没完成输出No和还有几个单元没完成。
例:2*2矩阵,初始站在00位置,指令是WSWS,答案:No,2
解答情况:过了81%,解答错误。
思路:暴力
时空复杂度:n,1
解法:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
String instructions = sc.next();
HashSet<String> set = new HashSet<>();
int[][] matrix = new int[n][m];
int curX = 0, curY = 0;
matrix[curX][curY] = 1;
int num = 0;
for (int i = 0; i < instructions.length(); i++) {
if (instructions.charAt(i) == 'W') {
curX = curX - 1;
} else if (instructions.charAt(i) == 'S') {
curX = curX + 1;
} else if (instructions.charAt(i) == 'A') {
curY = curY - 1;
} else if (instructions.charAt(i) == 'D') {
curY = curY + 1;
}
matrix[curX][curY] = 1;
StringBuilder sb = new StringBuilder();
sb.append(curX);
sb.append(curY);
set.add(new String(sb));
if (set.size() == n * m) {
num = i;
break;
}
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (matrix[i][j] == 0) {
res++;
}
}
}
if (res == 0) {
System.out.println("Yes\n" + num);
} else {
System.out.println("No\n" + res);
}
} 第三题、模拟,将数组中首部的数放到尾部,重复两次,然后删除第一个元素,直到没有元素。给你结果,还原这个数组。 例:【1,2,3,4】,答案:【4,2,1,3】
解答情况:过了81%,解答错误。
思路:逆向思维。倒序。添加元素,将数组中尾部的元素放到首部,重复两次。
第一次:放入【4】,
第二次:放入3,【3,4】,removeLast(),addFirst(),removeLast(),addFirst(),还是【3,4】
第三次:放入2,【2,3,4】,。。。,【3,4,2】
第四次:放入1,【1,3,4,2】,。。。,【4,2,1,3】
时空复杂度:n,n
解法:
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 < n; i++) {
nums[i] = sc.nextInt();
}
LinkedList<Integer> list = new LinkedList<>();
for (int i = nums.length - 1; i >= 0; i--) {
list.addFirst(nums[i]);
Integer last = list.removeLast();
list.addFirst(last);
Integer secondeLast = list.removeLast();
list.addFirst(secondeLast);
}
for (Integer integer : list) {
System.out.println(integer);
}
} 第四题、求三元组,满足i<j<k&&nums【i】-2nums【j】=2*nums【j】-nums【k】
思路:暴力
解答情况:81%,超时
时空复杂度:n3,1
解法:
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 < n; i++) {
nums[i] = sc.nextInt();
}
int res = 0;
for (int i = 0; i < n - 2; i++) {
int a = nums[i];
for (int j = i + 1; j < n - 1; j++) {
int b = nums[j];
for (int k = j + 1; k < n; k++) {
int c = nums[k];
if (a - b == 2 * b - c) {
res++;
}
}
}
}
System.out.println(res);
} 第五题、节点之和最大的路径
例:【1,2,3】,root=1,left=2,right=3,最大和是4.
解答情况:ac。
思路:力扣原题
时空复杂度:n,n
解法:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] nums = new int[n+1];
for (int i = 1; i <= n; i++) {
nums[i] = sc.nextInt();
}
int res = traverse(1, nums);
System.out.println(res);
}
private static int traverse(int index, int[] nums) {
if (index < 0 || index >= nums.length) {
return 0;
}
int left = traverse(index * 2, nums);
int right = traverse(index * 2 + 1, nums);
return Math.max(left, right) + nums[index];
} 