欢迎大家加QQ群:623375442,可以方便群里面交流。

100310. Special Array I

如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。

Aging 有一个整数数组 nums。如果 nums 是一个 特殊数组 ,返回 true,否则返回 false。

测试样例:

输入:nums = [1]

输出:true

解释:只有一个元素,所以答案为 true。

解答:暴力扫描一下

class Solution {
    public boolean isArraySpecial(int[] nums) {
        for (int i = 1; i < nums.length; ++i) {
            if (nums[i] % 2 == nums[i - 1] % 2) {
                return false;
            }
        }
        return true;
    }
}

100308. Special Array II

如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。

周洋哥有一个整数数组 nums 和一个二维整数矩阵 queries,对于 queries[i] = [fromi, toi],请你帮助周洋哥检查子数组 nums[fromi..toi] 是不是一个 特殊数组 。

返回布尔数组 answer,如果 nums[fromi..toi] 是特殊数组,则 answer[i] 为 true ,否则,answer[i] 为 false 。

测试样例:

输入:nums = [4,3,1,6], queries = [[0,2],[2,3]]

输出:[false,true]

解释:子数组是 [4,3,1]。3 和 1 都是奇数。因此这个查询的答案是 false。子数组是 [1,6]。只有一对:(1,6),且包含了奇偶性不同的数字。因此这个查询的答案是 true。

解答:首先计算符合要求的区间,并存在一颗红黑树中。扫描query,查看每次query是否落在复合要求的区间中。

class Solution {
    public boolean[] isArraySpecial(int[] nums, int[][] queries) {
        int st = 0;
        TreeSet<int[]> set = new TreeSet<>((a, b) -> (Integer.compare(a[0], b[0])));
        for (int i = 1; i <= nums.length; ++i) {
            if (i == nums.length || nums[i] % 2 == nums[i - 1] % 2) {
                set.add(new int[]{st, i - 1});
                st = i;
            }
        }
        boolean[] res = new boolean[queries.length];
        for (int i = 0; i < queries.length; ++i) {
            int[] first = set.floor(queries[i]);
            if (first != null && first[1] >= queries[i][1]) {
                res[i] = true;
            }
        }
        return res;
    }
}

100300. Sum of Digit Differences of All Pairs

车尔尼有一个数组 nums ,它只包含 正 整数,所有正整数的数位长度都 相同 。

两个整数的 数位不同 指的是两个整数 相同 位置上不同数字的数目。

请车尔尼返回 nums 中 所有 整数对里,数位不同之和。

测试样例:

输入:nums = [13,23,12]

输出:4

解释:计算过程如下:

  • 13 和 23 的数位不同为 1 。
  • 13 和 12 的数位不同为 1 。
  • 23 和 12 的数位不同为 2 。

所以所有整数数对的数位不同之和为 1 + 1 + 2 = 4 。

解答:手速场,没仔细看,只需要计算不同的数目。先把每一位的数字分布情况记录下来,然后枚举一下不同的个数。

class Solution {
    public long sumDigitDifferences(int[] nums) {
        long res = 0, mod = 10;
        for (int i = 0; i < 30; ++i) {
            long div = mod / 10;
            int[] count = new int[10];
            // 记录当前数位的数字分布情况
            for (int n : nums) {
                count[(int) (n % mod / div)] += 1;
            }
            res += calDiff(count);
            mod *= 10;
        }
        return res;
    }

    private long calDiff(int[] count) {
        long total = 0;
        for (int n : count) {
            total += n;
        }
        long res = 0;

        // 累和不同的个数
        for (int n : count) {
            total -= n;
            res += total * n;
        }
        return res;
    }
}

100298. Find Number of Ways to Reach the K-th Stair

给你有一个 非负 整数 k 。有一个无限长度的台阶,最低 一层编号为 0 。

虎老师有一个整数 jump ,一开始值为 0 。虎老师从台阶 1 开始,虎老师可以使用 任意 次操作,目标是到达第 k 级台阶。假设虎老师位于台阶 i ,一次 操作 中,虎老师可以:

  • 向下走一级到 i - 1 ,但该操作 不能 连续使用,如果在台阶第 0 级也不能使用。
  • 向上走到台阶 i + 2jump 处,然后 jump 变为 jump + 1 。

请你返回虎老师到达台阶 k 处的总方案数。

注意 ,虎老师可能到达台阶 k 处后,通过一些操作重新回到台阶 k 处,这视为不同的方案。

测试样例:

输入:k = 0

输出:2

解释:2 种到达台阶 0 的方案为:

  • 虎老师从台阶 1 开始。
    • 执行第一种操作,从台阶 1 向下走到台阶 0 。
  • 虎老师从台阶 1 开始。
  • 执行第一种操作,从台阶 1 向下走到台阶 0 。
    • 执行第二种操作,向上走 20 级台阶到台阶 1 。
    • 执行第一种操作,从台阶 1 向下走到台阶 0 。

解答:这题还是挺简单的,BFS暴力枚举就行了。

class Solution {
    public int waysToReachStair(int k) {
        HashMap<Long, Integer> total = initialMap(), cur = initialMap();
        int jump = 0;
        while (!cur.isEmpty()) {
            HashMap<Long, Integer> next = new HashMap<>();
            for (Map.Entry<Long, Integer> kv : cur.entrySet()) {
                long tmp = kv.getKey() + (1L << jump);
                // BFS 暴力下一种情况
                // 大于K的就直接扔掉。因为下一次必然还是Type 2
                if (tmp <= k) {
                    next.put(tmp, next.getOrDefault(tmp, 0) + kv.getValue());
                    total.put(tmp, total.getOrDefault(tmp, 0) + kv.getValue());
                }
                // Type 1在BFS已经计算,下一次必然是Type 2
                if (tmp - 1 <= k) {
                    next.put(tmp - 1, next.getOrDefault(tmp - 1, 0) + kv.getValue());
                    total.put(tmp - 1, total.getOrDefault(tmp - 1, 0) + kv.getValue());
                }
            }
            ++jump;
            cur = next;
        }
        return total.getOrDefault((long) k, 0);
    }

    private HashMap<Long, Integer> initialMap() {
        HashMap<Long, Integer> map = new HashMap<>();
        map.put(1L, 1);
        map.put(0L, 1);
        return map;
    }
}

Leave a Reply

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