100263. Harshad Number

如果一个整数能够被其各个数位上的数字之和整除,则称之为 哈沙德数(Harshad number)。给你一个整数 x 。如果 x 是 哈沙德数 ,则返回 x 各个数位上的数字之和,否则,返回 -1 。

测试样例:

输入:18

输出:9

解释:x 各个数位上的数字之和为 9 。18 能被 9 整除。因此 18 是哈沙德数,答案是 9 。

解答:按照题意计算。

class Solution {
    public int sumOfTheDigitsOfHarshadNumber(int x) {
        String t = String.valueOf(x);
        int add = 0;
        for (int i = 0; i < t.length(); ++i) {
            add += (t.charAt(i) - '0');
        }
        return x % add == 0 ? add : -1;
    }
}

100235. Water Bottles II

给你两个整数 numBottles 和 numExchange 。

numBottles 代表你最初拥有的满水瓶数量。在一次操作中,你可以执行以下操作之一:

  • 喝掉任意数量的满水瓶,使它们变成空水瓶。
  • 用 numExchange 个空水瓶交换一个满水瓶。然后,将 numExchange 的值增加 1 。

注意,你不能使用相同的 numExchange 值交换多批空水瓶。例如,如果 numBottles == 3 并且 numExchange == 1 ,则不能用 3 个空水瓶交换成 3 个满水瓶。

返回你 最多 可以喝到多少瓶水。

测试样例:

输入:numBottles = 13, numExchange = 6

输出:15

解释:上表显示了满水瓶的数量、空水瓶的数量、numExchange 的值,以及累计喝掉的水瓶数量。

解答:范围不大,按照题意暴力计算。

class Solution {
    public int maxBottlesDrunk(int numBottles, int numExchange) {
        int emptyBottles = 0;
        int res = 0;
        while (true) {
            res += numBottles;
            emptyBottles += numBottles;
            numBottles = 0;
            if (emptyBottles < numExchange) {
                break;
            }
            while (emptyBottles >= numExchange) {
                ++numBottles;
                emptyBottles -= numExchange;
                ++numExchange;
            }
        }
        return res;
    }
}

100266. Count Alternating Subarrays

给你一个二进制数组 nums 。

如果一个子数组中 不存在 两个 相邻 元素的值 相同 的情况,我们称这样的子数组为 交替子数组 。

返回数组 nums 中交替子数组的数量。

测试样例:

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

输出:5

解释:以下子数组是交替子数组:[0] 、[1] 、[1] 、[1] 以及 [0,1] 。

解答:碰到两个相邻数字相同时,累和截断变成1,否则不断累和。并且增加一个long res对象,累和累和。

class Solution {
    public long countAlternatingSubarrays(int[] nums) {
        long res = 0;
        int add = 0, last = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; ++i) {
            if (nums[i] != last) {
                ++add;
            } else {
                add = 1;
            }
            res += add;
            last = nums[i];
        }
        return res;
    }
}

100240. Minimize Manhattan Distances

给你一个下标从 0 开始的数组 points ,它表示二维平面上一些点的整数坐标,其中 points[i] = [xi, yi] 。

两点之间的距离定义为它们的曼哈顿距离。

请你恰好移除一个点,返回移除后任意两点之间的 最大 距离可能的 最小 值。

测试样例:

输入:points = [[3,10],[5,15],[10,2],[4,4]]

输出:12

解释:移除每个点后的最大距离如下所示:

  • 移除第 0 个点后,最大距离在点 (5, 15) 和 (10, 2) 之间,为 |5 - 10| + |15 - 2| = 18 。
  • 移除第 1 个点后,最大距离在点 (3, 10) 和 (10, 2) 之间,为 |3 - 10| + |10 - 2| = 15 。
  • 移除第 2 个点后,最大距离在点 (5, 15) 和 (4, 4) 之间,为 |5 - 4| + |15 - 4| = 12 。
  • 移除第 3 个点后,最大距离在点 (5, 15) 和 (10, 2) 之间的,为 |5 - 10| + |15 - 2| = 18 。

在恰好移除一个点后,任意两点之间的最大距离可能的最小值是 12 。

解答:这道题目的关键是要明白:|Xi – Xj| + |Yi – Yj| = max((Xi – Yi) – (Xj – Yj), (-Xi + Yi) – (-Xj + Yj), (-Xi – Yi) – (-Xj – Yj), (Xi + Yi) – (Xj + Yj))。只要寻找到max(xi + y1), min(xi + y1), max(xi - y1), min(xi - y1),四个位置,然后计算去掉这四个位置之后的最小值就行了。

class Solution {
    public int minimumDistance(int[][] points) {
        int len = points.length;
        int[] sum = new int[len], diff = new int[len];
        for (int i = 0; i < points.length; ++i) {
            sum[i] = points[i][0] + points[i][1];
            diff[i] = points[i][0] - points[i][1];
        }
        int[] removeCand = findPos(sum, diff);
        int res = Integer.MAX_VALUE;
        for (int n : removeCand) {
            res = Math.min(res, minimumDistance(sum, diff, n));
        }
        return res;
    }

    private int[] findPos(int[] sum, int[] diff) {
        int minsum, maxsum, mindiff, maxdiff;
        minsum = maxsum = 0;
        mindiff = maxdiff = 0;
        for (int i = 1; i < sum.length; i++) {
            if (sum[i] < sum[minsum]){
                minsum = i;
            } else if (sum[i] > sum[maxsum]){
                maxsum = i;
            }

            if (diff[i] < diff[mindiff]) {
                mindiff = i;
            }
            else if (diff[i] > diff[maxdiff]) {
                maxdiff = i;
            }
        }
        return new int[]{minsum, maxsum, mindiff, maxdiff};
    }

    private int minimumDistance(int[] sum, int[] diff, int skip) {
        int minsum = Integer.MAX_VALUE, maxsum = Integer.MIN_VALUE, mindiff = Integer.MAX_VALUE, maxdiff = Integer.MIN_VALUE;
        for (int i = 0; i < sum.length; ++i) {
            if (i == skip) continue;
            if (sum[i] < minsum) {
                minsum = sum[i];
            }
            if (sum[i] > maxsum) {
                maxsum = sum[i];
            }

            if (diff[i] < mindiff) {
                mindiff = diff[i];
            }
            if (diff[i] > maxdiff) {
                maxdiff = diff[i];
            }
        }
        return Math.max(maxsum - minsum, maxdiff - mindiff);
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *