leetcode第146周赛

96 篇文章 1 订阅
81 篇文章 1 订阅

https://leetcode-cn.com/contest/weekly-contest-146
这次周赛,因为有事没有参加,今天写完代码

题1
等价多米诺骨牌对的数量
肯定不能一个个遍历,题目给了提示,数字都是从1到9,总共也就9*9=81个可能嘛

public int numEquivDominoPairs(int[][] dominoes) {
    int[][] ans = new int[10][10];
    for (int i = 0; i < dominoes.length; i++) {
        ans[dominoes[i][0]][dominoes[i][1]]++;
    }
    int res = 0;
    for (int i = 1; i <= 9; i++) {
        for (int j = i + 1; j <= 9; j++) {
			//防止重复计算,从i+1开始
			//这是在计算反转后一致的
            res += ans[i][j] * ans[j][i];
        }
        for (int j = 1; j <= 9; j++) {
			//这是计算,不反转一致的
            res += ans[i][j] * (ans[i][j] - 1) / 2;
        }
    }
    return res;
}

题2
颜色交替的最短路径
这个不能呢按最优规划算,有点类似挖地雷

public int[] shortestAlternatingPaths(int n, int[][] red_edges, int[][] blue_edges) {
    Map<Integer, Set<Integer>> redMap = new HashMap<>();
    Map<Integer, Set<Integer>> blueMap = new HashMap<>();
    for (int i = 0; i < red_edges.length; i++) {
        Set<Integer> set = redMap.get(red_edges[i][0]);
        if (set == null) {
            set = new HashSet<>();
            redMap.put(red_edges[i][0], set);
        }
        set.add(red_edges[i][1]);
    }
    for (int i = 0; i < blue_edges.length; i++) {
        Set<Integer> set = blueMap.get(blue_edges[i][0]);
        if (set == null) {
            set = new HashSet<>();
            blueMap.put(blue_edges[i][0], set);
        }
        set.add(blue_edges[i][1]);
    }
    int[] ans = new int[n];
    ans[0] = 0;
    for (int i = 1; i < n; i++) {
        ans[i] = -1;
    }
    Set<Integer> pathA = new HashSet<>();
    Set<Integer> pathB = new HashSet<>();
    Set<Integer> allA = new HashSet<>();
    Set<Integer> allB = new HashSet<>();
    pathA.add(0);
    pathB.add(0);
    int k = 0;
    while (pathA.size() > 0 || pathB.size() > 0) {
        k++;
        List<Integer> pA = new ArrayList<>(pathA);
        List<Integer> pB = new ArrayList<>(pathB);
        pathA.clear();
        pathB.clear();
        for (Integer p : pA) {
            Set<Integer> set = redMap.get(p);
            if (set != null) {
                for (Integer i : set) {
                    if (!allB.contains(i)) {
                        pathB.add(i);
                        allB.add(i);
                        if (ans[i] == -1) {
                            ans[i] = k;
                        }
                    }
                }
            }
        }
        for (Integer p : pB) {
            Set<Integer> set = blueMap.get(p);
            if (set != null) {
                for (Integer i : set) {
                    if (!allA.contains(i)) {
                        pathA.add(i);
                        allA.add(i);
                        if (ans[i] == -1) {
                            ans[i] = k;
                        }
                    }
                }
            }
        }
    }

    return null;
}

题3
叶值的最小代价生成树
这个有点最优规划的意思,但是不想想太多,弄for,直接按递归写了

int[][][] dp;

public int mctFromLeafValues(int[] arr) {
    dp = new int[arr.length][arr.length][2];
    return max(arr, 0, arr.length - 1)[0];
}

private int[] max(int[] arr, int sta, int end) {
    if (dp[sta][end][1] > 0) {
        return dp[sta][end];
    }
    if (sta == end) {
        return new int[]{0, arr[sta]};
    }
    int ans = Integer.MAX_VALUE;
    int max = 0;
    for (int i = sta; i < end; i++) {
        int[] m1 = max(arr, sta, i);
        int[] m2 = max(arr, i + 1, end);
        ans = Math.min(ans, m1[0] + m2[0] + m1[1] * m2[1]);
        max = Math.max(m1[1], m2[1]);
    }
    dp[sta][end] = new int[]{ans, max};
    return dp[sta][end];
}

题4
绝对值表达式的最大值
这道题有点脑经急转弯的意思,我就区分讨论,按照值的正负,拆绝对值

public int maxAbsValExpr(int[] arr1, int[] arr2) {
    int len = arr1.length;
    int max1 = Integer.MIN_VALUE;
    int max2 = Integer.MIN_VALUE;
    int max3 = Integer.MIN_VALUE;
    int max4 = Integer.MIN_VALUE;
    int max5 = Integer.MIN_VALUE;
    int max6 = Integer.MIN_VALUE;
    int max7 = Integer.MIN_VALUE;
    int max8 = Integer.MIN_VALUE;
    for (int i = 0; i < len; i++) {
        max1 = Math.max(arr1[i] + arr2[i] + i, max1);
        max2 = Math.max(arr1[i] + arr2[i] - i, max2);
        max3 = Math.max(0 - arr1[i] + arr2[i] + i, max3);
        max4 = Math.max(0 - arr1[i] + arr2[i] - i, max4);
        max5 = Math.max(arr1[i] - arr2[i] + i, max5);
        max6 = Math.max(arr1[i] - arr2[i] - i, max6);
        max7 = Math.max(-arr1[i] - arr2[i] + i, max7);
        max8 = Math.max(-arr1[i] - arr2[i] - i, max8);
    }
    return Math.max(Math.max(max1 + max8, max2 + max7), Math.max(max3 + max6, max4 + max5));

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值