LeetCode刷题记203-Geometry(几何)

面试题 16.03. 交点

class Solution {
    public boolean inLine(double x, double y, double x1, double y1, double x2, double y2) {
        if (y >= Math.min(y1, y2) && y <= Math.max(y1, y2) &&
            x >= Math.min(x1, x2) && x <= Math.max(x1, x2)) return true;
        return false;
    }

    public double[] intersection(int[] start1, int[] end1, int[] start2, int[] end2) {
        int dx1 = start1[0] - end1[0];
        int dy1 = start1[1] - end1[1];
        int dx2 = start2[0] - end2[0];
        int dy2 = start2[1] - end2[1];

        if (dx1 == 0 && dx2 != 0) {
            double k2 = (double)dy2 / dx2;
            double b2 = (double)start2[1] - k2 * start2[0]; 
            double x = start1[0];
            double y = k2 * x + b2;
            if (inLine(x, y, start1[0], start1[1], end1[0], end1[1]) &&
                inLine(x, y, start2[0], start2[1], end2[0], end2[1])) {
                return new double[]{x, y};
            }
        } else if (dx2 == 0 && dx1 != 0) {
            double k1 = (double)dy1 / dx1;
            double b1 = (double)start1[1] - k1 * start1[0]; 
            double x = start2[0];
            double y = k1 * x + b1;
            if (inLine(x, y, start1[0], start1[1], end1[0], end1[1]) &&
                inLine(x, y, start2[0], start2[1], end2[0], end2[1])) {
                return new double[]{x, y};
            }
        } else if (dx2 == 0 && dx1 == 0) {
            if (start1[0] == start2[0]) {
                int x = start1[0];
                int y1_h, y1_l, y2_h, y2_l;
                if (Math.min(start1[1], end1[1]) >= Math.min(start2[1], end2[1])) {
                    y1_l = Math.min(start1[1], end1[1]);
                    y1_h = Math.max(start1[1], end1[1]);

                    y2_l = Math.min(start2[1], end2[1]);
                    y2_h = Math.max(start2[1], end2[1]);
                } else {
                    y2_l = Math.min(start1[1], end1[1]);
                    y2_h = Math.max(start1[1], end1[1]);

                    y1_l = Math.min(start2[1], end2[1]);
                    y1_h = Math.max(start2[1], end2[1]);
                }
                
                if (y1_l <= y2_h) {
                    return new double[]{x, y1_l};
                }
            }
        } else {
            double k1 = (double)dy1 / dx1;
            double b1 = (double)start1[1] - k1 * start1[0]; 

            double k2 = (double)dy2 / dx2;
            double b2 = (double)start2[1] - k2 * start2[0]; 

            if (k1 == k2) {
                if (b1 == b2) {
                    int y;
                    int x1_h, x1_l, x2_h, x2_l;
                    if (Math.min(start1[0], end1[0]) >= Math.min(start2[0], end2[0])) {
                        x1_l = Math.min(start1[0], end1[0]);
                        x1_h = Math.max(start1[0], end1[0]);
                        if (start1[0] < end1[0]) y = start1[1];
                        else y = end1[1];

                        x2_l = Math.min(start2[0], end2[0]);
                        x2_h = Math.max(start2[0], end2[0]);
                    } else {
                        x2_l = Math.min(start1[0], end1[0]);
                        x2_h = Math.max(start1[0], end1[0]);

                        x1_l = Math.min(start2[0], end2[0]);
                        x1_h = Math.max(start2[0], end2[0]);
                        if (start2[0] < end2[0]) y = start2[1];
                        else y = end2[1];
                    }
                    if (x1_l <= x2_h) {
                        return new double[]{x1_l, y};
                    }
                } 
            } else {
                double x = (b2 - b1) / (k1 - k2);
                double y = k1 * x + b1;
                if (inLine(x, y, start1[0], start1[1], end1[0], end1[1]) &&
                    inLine(x, y, start2[0], start2[1], end2[0], end2[1])) {
                    return new double[]{x, y};
                }
            }
        }
        return new double[]{};
    }
}

面试题 16.13. 平分正方形

class Solution {
    public void swapSquares(int[] square1, int[] square2) {
        for (int i = 0; i < 3; i ++) {
            int tmp = square1[i];
            square1[i] = square2[i];
            square2[i] = tmp;
        }
    }
    public double[] cutSquares(int[] square1, int[] square2) {
        if (square1[0] > square2[0]) {
            swapSquares(square1, square2);
        } 
        double x1 = square1[0] + square1[2] / 2.0;
        double y1 = square1[1] + square1[2] / 2.0;
        double x2 = square2[0] + square2[2] / 2.0;
        double y2 = square2[1] + square2[2] / 2.0;

        if (x1 == x2) {
            return new double[]{x1, Math.min(square1[1], square2[1]), x2, Math.max(square1[1] + square1[2], square2[1] + square2[2])};
        }

        double k = (y1 - y2) / (x1 - x2);
        double b = y1 - k * x1;
        if (Math.abs(k) <= 1) {
            x1 = square1[0];
            x2 = Math.max(square1[0] + square1[2], square2[0] + square2[2]);
            return new double[]{x1, k * x1 + b, x2, k * x2 + b};
        } else {
            y1 = Math.min(square1[1], square2[1]);
            y2 = Math.max(square1[1] + square1[2], square2[1] + square2[2]);
            x1 = (y1 - b) / k;
            x2 = (y2 - b) / k;
            if (x1 < x2) return new double[]{x1, y1, x2, y2};
            else return new double[]{x2, y2, x1, y1};
        }
        
    }
}

587. 安装栅栏

class Solution {
    public double getDis(double x1, double y1, double x2, double y2) {
        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }
    public int getCrossProduct(int x0, int y0, int x1, int y1, int x2, int y2) { // 叉积
        int X1 = x1 - x0;
        int Y1 = y1 - y0;
        int X2 = x2 - x0;
        int Y2 = y2 - y0; 
        return X1 * Y2  - X2 * Y1;  // 小于0, 顺时针
    }
    public int[][] outerTrees(int[][] points) {
        if (points.length <= 3) return points;
    
        int[] sta = new int[points.length];
        int top = 0;

        int minXId = 0;
        for (int i = 1; i < points.length; i ++) {
            if (points[i][1] < points[minXId][1]) {
                minXId = i;
            }
        }
        int tmp = points[minXId][0];
        points[minXId][0] = points[0][0];
        points[0][0] = tmp;
        tmp = points[minXId][1];
        points[minXId][1] = points[0][1];
        points[0][1] = tmp;

        int[][] a = new int[points.length - 1][2];
        System.arraycopy(points, 1, a, 0, points.length - 1);
        Arrays.sort(a, new Comparator<int[]>(){
            @Override 
            public int compare(int[] a, int[] b) {
                int c = getCrossProduct(points[0][0], points[0][1], a[0], a[1], b[0], b[1]);
                if (c < 0) return 1;
                if (c > 0) return -1;
                if (a[0] < b[0]) return -1;
                if (a[0] > b[0]) return 1;
                if (a[1] > b[1]) return -1;
                if (a[1] < b[1]) return 1;
                return 0; 
            }
        });


        System.arraycopy(a, 0, points, 1, points.length - 1);

        int fro = 0;
        for (; fro < points.length; fro ++) {
            if (points[fro][0] != points[0][0]) {
                break;
            }
        }
        sta[top ++] = 0;
        for (int i = fro - 1; i > 0; i --) {
            sta[top ++] = i;
        }
        if (fro == points.length) {
            int[][] ans = new int[top][2];
            for (int i = 0; i < top; i ++) {
                ans[i] = points[sta[i]];
            }
            return ans;
        }
        sta[top ++] = fro;
        
        for (int i = fro + 1; i < points.length; i ++) {
            while (top >= 2) {
                int c = getCrossProduct(
                        points[sta[top - 2]][0], points[sta[top - 2]][1], 
                        points[sta[top - 1]][0], points[sta[top - 1]][1],
                        points[i][0], points[i][1]);
                if (c < 0) {
                    top --;
                } else {
                    break;
                }
            }
            sta[top ++] = i;
        }
        while (top >= 2) {
            int c = getCrossProduct(
                        points[sta[top - 2]][0], points[sta[top - 2]][1], 
                        points[sta[top - 1]][0], points[sta[top - 1]][1],
                        points[0][0], points[0][1]);
            if (c < 0) {
                top --;
            } else {
                break;
            }
        }
        int[][] ans = new int[top][2];
        for (int i = 0; i < top; i ++) {
            ans[i] = points[sta[i]];
        }
        return ans;
    }
}

1515. 服务中心的最佳位置

你可能感兴趣的:(leetcode,几何)