上岸算法 I LeetCode Weekly Contest 244解题报告

卖大米 2021-6-8 306


No.1判断矩阵经轮转后是否一致

解题思路

模拟矩阵的旋转即可。

代码展示


**classSolution**{
    **publicbooleanfindRotation**(**int**[][] mat, **int**[][] target){
        **for** (**int** i = 0; i < 4; i++) {
            **if** (equal(mat, target)) {
                **returntrue**;
            }
            mat = rotate(mat);
        }
        **returnfalse**;
    }

    **privateint**[][] rotate(**int**[][] mat) {
        **int**[][] r = **newint**[mat.length][mat[0].length];
        **for** (**int** i = 0, y = 0; i < mat.length; i++, y++) {
            **for** (**int** j = 0, x = mat.length - 1; j < mat[0].length; j++, x--) {
                r[i][j] = mat[x][y];
            }
        }
        **return** r;
    }

    **booleanequal**(**int**[][] mat, **int**[][] target){
        **for** (**int** i = 0; i < mat.length; i++) {
            **for** (**int** j = 0; j < mat[0].length; j++) {
                **if** (mat[i][j] != target[i][j]) {
                    **returnfalse**;
                }
            }
        }
        **returntrue**;
    }
}

上岸公开公开课,毫无保留地将业界面试核心知识免费传授给大家,并配有课前课后习题以及标准答案集以方便大家学习。

长达近30小时的核心课程帮助大家掌握所有面试必备知识,在一个月内有效突破算法面试认知,从而有自信面对FAANG的挑战。

添加上岸小年糕,发送【公开课】即可领取

No.2 使数组元素相等的减少操作次数

解题思路

简单暴力地,从大到小依次处理每个元素即可。使用 TreeMap 的代码非常简洁,或者可以使用链表,速度更快。

代码展示


**classSolution**{
    public int reductionOperations(int[] nums) {
        TreeMap<Integer, Integer> count = **new** TreeMap<>();
        **for** (**var**num : nums) {
            count.put(num, count.getOrDefault(num, 0) + 1);
        }
        int result = 0;
        **while** (count.size() > 1) {
            **var** largest = count.pollLastEntry();
            **var** nextLargest = count.lastEntry();
            result += largest.getValue();
            count.put(nextLargest.getKey(), nextLargest.getValue() + largest.getValue());
        }
        **return** result;
    }
}

No.3 使二进制字符串字符交替的最少反转次数

解题思路

枚举类型 1 操作执行的次数即可。

执行完类型 1 的操作之后,需要执行的类型 2 的操作次数是固定的。

我们只需要知道奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量就可以计算出类型 2 的操作次数。

每执行一次类型 1 的操作,奇数下标上 0 和 1 的数量、偶数下标上 0 和 1 的数量的变化都可以 O(1) 地计算出来。

代码展示


class Solution {
    public int minFlips(String s) {
        char[] str = s.toCharArray();
        // count[0] 表示偶数下标上 0 和 1 的数量
        // count[1] 表示奇数下标上 0 和 1 的数量
        int[][] count = new int[2][2];
        for (int i = 0; i < str.length; i++) {
            count[i % 2][str[i] - '0']++;
        }
        intresult = Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]);
        for (inti = 0;i < str.length-1; i++) {
            count[0][str[i] - '0']--;
            inttmp = count[1][0];
            count[1][0] = count[0][0];
            count[0][0] = tmp;
            tmp = count[1][1];
            count[1][1] = count[0][1];
            count[0][1] = tmp;
            count[(str.length-1) % 2][str[i] - '0']++;
            result = Math.min(result,Math.min(count[1][1] + count[0][0], count[1][0] + count[0][1]));
        }
        returnresult;
    }

No.4 装包裹的最小浪费空间

解题思路

二分查找。

对所有的包裹和供应商的盒子都排序,然后依次枚举每个供应商即可。

计算一个供应商的盒子的浪费空间时,从小到大使用每种盒子,每种盒子尽可能多装包裹即可,使用前缀和数组和二分查找可以快速计算结果。

代码展示


**classSolution** {
    **publicintminWastedSpace**(**int**[] packages, **int**[][] boxes){
        Arrays.sort(packages);
        **long**[] preSum = **newlong**[packages.length];
        preSum[0] = packages[0];
        **for** (**int** i = 1; i < preSum.length; i++) {
            preSum[i] = preSum[i - 1] + packages[i];
        }
        **long** result = -1;
        **for** (**int**[] box : boxes) {
            Arrays.sort(box);
            **long** t = waste(packages, preSum, box);
            **if** (t != -1 && (result == -1 || t < result)) {
                result = t;
            }
        }
        **return** (**int**) (result % 1000000007L);
    }

    **privatelongwaste**(**int**[] packages, **long**[] preSum, **int**[] boxes){
        **int** start = 0;
        **long** result = 0;
        **for** (**int** box : boxes) {
            **if** (box < packages[start]) {
                **continue**;
            }
            **int** index = binarySearch(packages, box);
            _// [start, index] 之间的包裹使用 box 装_
            result += (**long**) box * (index - start + 1) - preSum[index];
            **if** (start != 0) {
                result += preSum[start - 1];
            }
            start = index + 1;
            **if** (start >= packages.length) {
                **return** result;
            }
        }
        **return**-1;
    }

    **privateintbinarySearch**(**int**[] arr, **int** target){
        **int** l = 0, r = arr.length - 1;
        **while** (l + 1 < r) {
            **int** mid = (l + r) / 2;
            **if** (arr[mid] <= target) {
                l = mid;
            } **else** {
                r = mid;
            }
        }
        **return** arr[r] <= target ? r : l;
    }
}
最新回复 (0)
返回