251011 去哪儿AI面的笔试

侥幸做出来,分享一下

第一题

求nums中被三整除且不含三的数字个数

其中,可以对区间[l, r]进行一次操作,都+1或-1,也可以不操作。

求可能的个数的最大值和最小值

思路:分别计算+1和-1的差值数组后,计算它们最大连续子数组之和,得到最大值和最小值

import java.util.Scanner;


// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int n = in.nextInt();
            int nums[] = new int[n];
            for (int i = 0; i < n; i++) {
                nums[i] = in.nextInt();
            }
            // valid[0]表示原来nums数组的对应数字是否成立
            // valid[1]和valid[2]表示nums对应数字+1和-1后是否还成立
            int cnt = 0, valid[][] = new int[3][n];
            for (int i = 0; i < n; i++) {
                int x = nums[i], sum = 0;
                if (check(nums[i])) {
                    valid[0][i] = 1;
                    cnt++;
                }
                if (check(nums[i]+1)) {
                    valid[1][i] = 1;
                }
                if (check(nums[i]-1)) {
                    valid[2][i] = 1;
                }
            }
            int max = cnt, min = cnt;
            for (int i = 0; i < n; i++) {  // 分别计算+1和-1后的差值
                valid[1][i] -= valid[0][i];
                valid[2][i] -= valid[0][i];
            }
            int add1 = getBigest(valid[1]), add2 = getBigest(valid[2]);  // 计算差值的最大值
            for (int i = 0; i < n; i++) {
                valid[1][i] = -valid[1][i];
                valid[2][i] = -valid[2][i];
            }
            int del1 = -getBigest(valid[1]), del2 = -getBigest(valid[2]);  // 计算差值的最小值(即计算负数的最大值的相反数)
            int res[] = new int[2];
            res[0] = cnt + Math.max(add1, add2);
            res[1] = cnt + Math.min(del1, del2);
            System.out.println(res[0] + " " + res[1]);
        }
    }
    private static int getBigest(int nums[]) {  // 获得nums的最大连续子数组之和
        int n = nums.length;
        int cur = 0, res = -(int)1e9;
        for (int i = 0; i < n; i++) {
            cur += nums[i];
            res = Math.max(res, cur);
            if (cur < 0) cur = 0;
        }
        return res;
    }
    private static boolean check(int x) {  // x这个数字是否成立
        int sum = 0;
        while (x > 0) {
            int cur = x % 10;
            if (cur == 3) break;
            sum += cur;
            x /= 10;
        }
        return x == 0 && sum % 3 == 0;
    }
}

第二题

对于一个区间[l,r],g(b)表示这个区间的中位数,min(l,r)表示区间的最小值

计算所有区间的g(b) - min(l,r)的最大值

思路:遍历每一个可能的中位数,贪心可以想到,这个中位数所在的区间越大越好,直到边界,可以拿到最小的min(l,r)。用两个方向的前缀最小值避免重复计算

import java.util.Scanner;


// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int T = in.nextInt();
            for (int t = 0; t < T; t++) {
                int n = in.nextInt(), nums[] = new int[n];
                for (int i = 0; i < n; i++) nums[i] = in.nextInt();
                // 两个方向的前缀最小值
                int leftMin[] = new int[n], rightMin[] = new int[n];
                leftMin[0] = nums[0]; rightMin[n-1] = nums[n-1];
                for (int i = 1; i < n; i++) {
                    leftMin[i] = Math.min(leftMin[i-1], nums[i]);
                }
                for (int i = n-2; i >= 0; i--) {
                    rightMin[i] = Math.min(rightMin[i+1], nums[i]);
                }
                // 0 1 2 -> 
                // 0 1 2 3 4-> 
                int res = 0;
                for (int i = 0; i < n; i++) {
                    if (i <= n/2) {  // 中位数在左边,找到区间的右边界
                        int r = Math.min(n-1, i*2);
                        res = Math.max(res, nums[i] - leftMin[r]);
                    } else {  // 中位数在右边,找到区间的左边界
                        int l = i - (n-i);
                        res = Math.max(res, nums[i] - rightMin[l]);
                    }
                }
                System.out.println(res);
            }
        }
    }
}

全部评论

相关推荐

点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务