每日算法&面试题,大厂特训二十八天——第二十五天(条件语句)

168 阅读3分钟

「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」。

导读

在这里插入图片描述

肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!! 专栏导航:上岸之路

算法特训二十八天

给定由一些正数(代表长度)组成的数组 nums ,返回 由其中三个长度组成的、面积不为零的三角形的最大周长 。如果不能形成任何面积不为零的三角形,返回 0。

示例 1:

输入:nums = [2,1,2]
输出:5
示例 2:

输入:nums = [1,2,1]
输出:0

思路:不失一般性,我们假设三角形的边长 a,b,ca,b,c 满足 a \leq b \leq ca≤b≤c,那么这三条边组成面积不为零的三角形的充分必要条件为 a+b>ca+b>c。

基于此,我们可以选择枚举三角形的最长边 cc,而从贪心的角度考虑,我们一定是选「小于 cc 的最大的两个数」作为边长 aa 和 bb,此时最有可能满足 a+b>ca+b>c,使得三条边能够组成一个三角形,且此时的三角形的周长是最大的。

class Solution {
    public int largestPerimeter(int[] A) {
        Arrays.sort(A);
        for (int i = A.length - 1; i >= 2; --i) {
            if (A[i - 2] + A[i - 1] > A[i]) {
                return A[i - 2] + A[i - 1] + A[i];
            }
        }
        return 0;
    }
}


给你两个整数 x 和 y ,表示你在一个笛卡尔坐标系下的 (x, y) 处。同时,在同一个坐标系下给你一个数组 points ,其中 points[i] = [ai, bi] 表示在 (ai, bi) 处有一个点。当一个点与你所在的位置有相同的 x 坐标或者相同的 y 坐标时,我们称这个点是 有效的 。

请返回距离你当前位置 曼哈顿距离 最近的 有效 点的下标(下标从 0 开始)。如果有多个最近的有效点,请返回下标 最小 的一个。如果没有有效点,请返回 -1 。

两个点 (x1, y1) 和 (x2, y2) 之间的 曼哈顿距离 为 abs(x1 - x2) + abs(y1 - y2) 。

示例 1:

输入:x = 3, y = 4, points = [[1,2],[3,1],[2,4],[2,3],[4,4]]
输出:2
解释:所有点中,[3,1],[2,4] 和 [4,4] 是有效点。有效点中,[2,4] 和 [4,4] 距离你当前位置的曼哈顿距离最小,都为 1 。[2,4] 的下标最小,所以返回 2
示例 2:

输入:x = 3, y = 4, points = [[3,4]]
输出:0
提示:答案可以与你当前所在位置坐标相同。
示例 3:

输入:x = 3, y = 4, points = [[2,3]]
输出:-1
解释:没有 有效点。
class Solution {
    public int nearestValidPoint(int x, int y, int[][] points) {
        ArrayList<Point> arrayList = new ArrayList<>();
        // 对每一个符合要求的点进行存储
        for (int idx = 0; idx < points.length; ++idx) {
            int[] point = points[idx];
            if (point[0] == x || point[1] == y) arrayList.add(new Point(point[0], point[1], idx));
        }
        // 排序,其相对大小与指定的 [x, y] 点计算曼哈顿距离来判断
        arrayList.sort(new Comparator<Point>() {
            @Override
            public int compare(Point o1, Point o2) {
                return distance(o1, x, y) - distance(o2, x, y);
            }
        });
        // 最后检查返回值
        return arrayList.isEmpty() ? -1 : arrayList.get(0).idx;
    }

    private int distance(Point p, int x, int y) {
        return Math.abs(p.x - x) + Math.abs(p.y - y);
    }

    static class Point {
        // x, y 就是原来的坐标轴
        // idx 是在原来数组中的下标
        int x, y;
        int idx;

        Point(int x, int y, int idx) {
            this.x = x;
            this.y = y;
            this.idx = idx;
        }
    }
}


面试题

ThreadPoolExecutor 线程池,corePoolSize=5,
maximumPoolSize=10,queueCapacity=10,有 20 个耗时任务 交给这个线程池执行,线程池会如何执行这 20 个任务?


 如果当前线程数<corePoolSize,如果是则创建新的线程执行该任务 。
 如果当前线程数>=corePoolSize,则将任务存入 BlockingQueue 。
 如果阻塞队列已满,且当前线程数<maximumPoolSize,则新建线程执行该任务。
 如果阻塞队列已满,且当前线程数>=maximumPoolSize,则抛出异常 。

 RejectedExecutionException,告诉调用者无法再接受任务了




给用户发消息任务超出队列,你用哪个拒绝策略?有其他方法吗 ?
ThreadPoolExecutor.CallerRunsPolicy
 无界队列(LinkedBlockingQuene),继续添加任务到阻塞队列中等待执行。
 用消息队列存任务数据,线程池慢慢处理。