【题解】—— LeetCode一周小结22

简介: LeetCode每日一道一周小结22
🌟欢迎来到 我的博客 —— 探索技术的无限可能!


🌟博客的简介(文章目录)


【题解】—— 每日一道题目栏


上接:【题解】—— LeetCode一周小结21

27.找出缺失的观测数据

题目链接:2028. 找出缺失的观测数据

现有一份 n + m 次投掷单个 六面 骰子的观测数据,骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份,你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n + m 次投掷数据的 平均值 。

给你一个长度为 m 的整数数组 rolls ,其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。

返回一个长度为 n 的数组,包含所有缺失的观测数据,且满足这 n + m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案,只需要返回其中任意一组即可。如果不存在答案,返回一个空数组。

k 个数字的 平均值 为这些数字求和后再除以 k 。

注意 mean 是一个整数,所以 n + m 次投掷的总和需要被 n + m 整除。

示例 1:

输入:rolls = [3,2,4,3], mean = 4, n = 2

输出:[6,6]

解释:所有 n + m 次投掷的平均值是 (3 + 2 + 4 + 3 + 6 + 6) / 6 = 4 。

示例 2:

输入:rolls = [1,5,6], mean = 3, n = 4

输出:[2,3,2,2]

解释:所有 n + m 次投掷的平均值是 (1 + 5 + 6 + 2 + 3 + 2 + 2) / 7 = 3 。

示例 3:

输入:rolls = [1,2,3,4], mean = 6, n = 4

输出:[]

解释:无论丢失的 4 次数据是什么,平均值都不可能是 6 。

示例 4:

输入:rolls = [1], mean = 3, n = 1

输出:[5]

解释:所有 n + m 次投掷的平均值是 (1 + 5) / 2 = 3 。

提示:

m == rolls.length

1 <= n, m <= 105

1 <= rolls[i], mean <= 6

题解:
方法:构造
        

class Solution {
   
    public int[] missingRolls(int[] rolls, int mean, int n) {
   
        int m = rolls.length;
        int s = (n + m) * mean;
        for (int v : rolls) {
   
            s -= v;
        }
        if (s > n * 6 || s < n) {
   
            return new int[0];
        }
        int[] ans = new int[n];
        Arrays.fill(ans, s / n);
        for (int i = 0; i < s % n; ++i) {
   
            ++ans[i];
        }
        return ans;
    }
}

28.找出峰值

题目链接:2951. 找出峰值

给你一个下标从 0 开始的数组 mountain 。你的任务是找出数组 mountain 中的所有 峰值。

以数组形式返回给定数组中 峰值 的下标,顺序不限 。

注意:

峰值 是指一个严格大于其相邻元素的元素。
数组的第一个和最后一个元素 不 是峰值。

示例 1:

输入:mountain = [2,4,4]

输出:[]

解释:

mountain[0] 和 mountain[2] 不可能是峰值,因为它们是数组的第一个和最后一个元素。

mountain[1] 也不可能是峰值,因为它不严格大于 mountain[2] 。

因此,答案为 [] 。

示例 2:

输入:mountain = [1,4,3,8,5]

输出:[1,3]

解释:

mountain[0] 和 mountain[4] 不可能是峰值,因为它们是数组的第一个和最后一个元素。

mountain[2] 也不可能是峰值,因为它不严格大于 mountain[3] 和 mountain[1] 。

但是 mountain[1] 和 mountain[3] 严格大于它们的相邻元素。

因此,答案是 [1,3] 。

提示:

3 <= mountain.length <= 100

1 <= mountain[i] <= 100

题解:
方法:遍历
        

class Solution {
   
    public List<Integer> findPeaks(int[] mountain) {
   
        List<Integer> ans = new ArrayList<>();
        for (int i = 1; i < mountain.length - 1; ++i) {
   
            if (mountain[i - 1] < mountain[i] && mountain[i + 1] < mountain[i]) {
   
                ans.add(i);
            }
        }
        return ans;
    }
}

29.找出出现至少三次的最长特殊子字符串 I

题目链接:2981. 找出出现至少三次的最长特殊子字符串 I

给你一个仅由小写英文字母组成的字符串 s 。

如果一个字符串仅由单一字符组成,那么它被称为 特殊 字符串。例如,字符串 "abc" 不是特殊字符串,而字符串 "ddd"、"zz" 和 "f" 是特殊字符串。

返回在 s 中出现 至少三次 的 最长特殊子字符串 的长度,如果不存在出现至少三次的特殊子字符串,则返回 -1 。

子字符串 是字符串中的一个连续 非空 字符序列。

示例 1:

输入:s = "aaaa"

输出:2

解释:出现三次的最长特殊子字符串是 "aa" :子字符串 "aaaa"、"aaaa" 和 "aaaa"。 可以证明最大长度是 2 。

示例 2:

输入:s = "abcdef"

输出:-1

解释:不存在出现至少三次的特殊子字符串。因此返回 -1 。

示例 3:

输入:s = "abcaba"

输出:1

解释:出现三次的最长特殊子字符串是 "a" :子字符串 "abcaba"、"abcaba" 和 "abcaba"。

可以证明最大长度是 1 。

提示:

3 <= s.length <= 50

s 仅由小写英文字母组成。

题解:
方法:二分查找 计数 滑动窗
        

class Solution {
   
    private String s;
    private int n;

    public int maximumLength(String s) {
   
        this.s = s;
        n = s.length();
        int l = 0, r = n;
        while (l < r) {
   
            int mid = (l + r + 1) >> 1;
            if (check(mid)) {
   
                l = mid;
            } else {
   
                r = mid - 1;
            }
        }
        return l == 0 ? -1 : l;
    }

    private boolean check(int x) {
   
        int[] cnt = new int[26];
        for (int i = 0; i < n;) {
   
            int j = i + 1;
            while (j < n && s.charAt(j) == s.charAt(i)) {
   
                j++;
            }
            int k = s.charAt(i) - 'a';
            cnt[k] += Math.max(0, j - i - x + 1);
            if (cnt[k] >= 3) {
   
                return true;
            }
            i = j;
        }
        return false;
    }
}

30.找出出现至少三次的最长特殊子字符串 II

题目链接:2982. 找出出现至少三次的最长特殊子字符串 II

给你一个仅由小写英文字母组成的字符串 s 。

如果一个字符串仅由单一字符组成,那么它被称为 特殊 字符串。例如,字符串 "abc" 不是特殊字符串,而字符串 "ddd"、"zz" 和 "f" 是特殊字符串。

返回在 s 中出现 至少三次 的 最长特殊子字符串 的长度,如果不存在出现至少三次的特殊子字符串,则返回 -1 。

子字符串 是字符串中的一个连续 非空 字符序列。

示例 1:

输入:s = "aaaa"

输出:2

解释:出现三次的最长特殊子字符串是 "aa" :子字符串 "aaaa"、"aaaa" 和 "aaaa"。

可以证明最大长度是 2 。

示例 2:

输入:s = "abcdef"

输出:-1

解释:不存在出现至少三次的特殊子字符串。因此返回 -1 。

示例 3:

输入:s = "abcaba"

输出:1

解释:出现三次的最长特殊子字符串是 "a" :子字符串 "abcaba"、"abcaba" 和 "abcaba"。 可以证明最大长度是 1

提示:

3 <= s.length <= 5 * 105

s 仅由小写英文字母组成。

题解:
方法:二分查找 滑动窗口 计数
        

class Solution {
   
    private String s;
    private int n;

    public int maximumLength(String s) {
   
        this.s = s;
        n = s.length();
        int l = 0, r = n;
        while (l < r) {
   
            int mid = (l + r + 1) >> 1;
            if (check(mid)) {
   
                l = mid;
            } else {
   
                r = mid - 1;
            }
        }
        return l == 0 ? -1 : l;
    }

    private boolean check(int x) {
   
        int[] cnt = new int[26];
        for (int i = 0; i < n;) {
   
            int j = i + 1;
            while (j < n && s.charAt(j) == s.charAt(i)) {
   
                j++;
            }
            int k = s.charAt(i) - 'a';
            cnt[k] += Math.max(0, j - i - x + 1);
            if (cnt[k] >= 3) {
   
                return true;
            }
            i = j;
        }
        return false;
    }
}

31.找出缺失和重复的数字

题目链接:2965. 找出缺失和重复的数字

给你一个下标从 0 开始的二维整数矩阵 grid,大小为 n * n ,其中的值在 [1, n2] 范围内。除了 a 出现 两次,b 缺失 之外,每个整数都 恰好出现一次 。

任务是找出重复的数字a 和缺失的数字 b 。

返回一个下标从 0 开始、长度为 2 的整数数组 ans ,其中 ans[0] 等于 a ,ans[1] 等于 b 。

示例 1:

输入:grid = [[1,3],[2,2]]

输出:[2,4]

解释:数字 2 重复,数字 4 缺失,所以答案是 [2,4] 。

示例 2:

输入:grid = [[9,1,7],[8,9,2],[3,4,6]]

输出:[9,5]

解释:数字 9 重复,数字 5 缺失,所以答案是 [9,5] 。

提示:

2 <= n == grid.length == grid[i].length <= 50

1 <= grid[i][j] <= n * n

对于所有满足1 <= x <= n * n 的 x ,恰好存在一个 x 与矩阵中的任何成员都不相等。

对于所有满足1 <= x <= n * n 的 x ,恰好存在一个 x 与矩阵中的两个成员相等。

除上述的两个之外,对于所有满足1 <= x <= n * n 的 x ,都恰好存在一对 i, j 满足 0 <= i, j <= n - 1
且 grid[i][j] == x 。

题解:
方法:计数
        

class Solution {
   
    public int[] findMissingAndRepeatedValues(int[][] grid) {
   
        int n = grid.length;
        int[] cnt = new int[n * n + 1];
        int[] ans = new int[2];
        for (int[] row : grid) {
   
            for (int x : row) {
   
                if (++cnt[x] == 2) {
   
                    ans[0] = x;
                }
            }
        }
        for (int x = 1;; ++x) {
   
            if (cnt[x] == 0) {
   
                ans[1] = x;
                return ans;
            }
        }
    }
}

2024.6

1.给小朋友们分糖果 I

题目链接:2928. 给小朋友们分糖果 I

给你两个正整数 n 和 limit 。

请你将 n 颗糖果分给 3 位小朋友,确保没有任何小朋友得到超过 limit 颗糖果,请你返回满足此条件下的 总方案数 。

示例 1:

输入:n = 5, limit = 2

输出:3

解释:总共有 3 种方法分配 5 颗糖果,且每位小朋友的糖果数不超过 2 :(1, 2, 2) ,(2, 1, 2) 和 (2, 2, 1)

示例 2:

输入:n = 3, limit = 3

输出:10

解释:总共有 10 种方法分配 3 颗糖果,且每位小朋友的糖果数不超过 3 :(0, 0, 3) ,(0, 1, 2) ,(0, 2, 1)
,(0, 3, 0) ,(1, 0, 2) ,(1, 1, 1) ,(1, 2, 0) ,(2, 0, 1) ,(2, 1, 0) 和
(3, 0, 0) 。

提示:

1 <= n <= 50

1 <= limit <= 50

题解:
方法:组合数学 枚举
        容斥原理

class Solution {
   
    public int distributeCandies(int n, int limit) {
   
        if (n > 3 * limit) {
   
            return 0;
        }
        long ans = comb2(n + 2);
        if (n > limit) {
   
            ans -= 3 * comb2(n - limit + 1);
        }
        if (n - 2 >= 2 * limit) {
   
            ans += 3 * comb2(n - 2 * limit);
        }
        return (int) ans;
    }

    private long comb2(int n) {
   
        return 1L * n * (n - 1) / 2;
    }
}

数学题单

==数学题单==


2.分糖果

题目链接:575. 分糖果

Alice 有 n 枚糖,其中第 i 枚糖的类型为 candyType[i] 。Alice 注意到她的体重正在增长,所以前去拜访了一位医生。

医生建议 Alice 要少摄入糖分,只吃掉她所有糖的 n / 2 即可(n 是一个偶数)。Alice 非常喜欢这些糖,她想要在遵循医生建议的情况下,尽可能吃到最多不同种类的糖。

给你一个长度为 n 的整数数组 candyType ,返回: Alice 在仅吃掉 n / 2 枚糖的情况下,可以吃到糖的 最多 种类数。

示例 1:

输入:candyType = [1,1,2,2,3,3]

输出:3

解释:Alice 只能吃 6 / 2 = 3 枚糖,由于只有 3 种糖,她可以每种吃一枚。

示例 2:

输入:candyType = [1,1,2,3]

输出:2

解释:Alice 只能吃 4 / 2 = 2 枚糖,不管她选择吃的种类是 [1,2]、[1,3] 还是
[2,3],她只能吃到两种不同类的糖。

示例 3:

输入:candyType = [6,6,6,6]

输出:1

解释:Alice 只能吃 4 / 2 = 2 枚糖,尽管她能吃 2 枚,但只能吃到 1 种糖。

提示:

n == candyType.length

2 <= n <= 104

n 是一个偶数

-105 <= candyType[i] <= 105

题解:
方法:哈希表
        

class Solution {
   
    public int distributeCandies(int[] candyType) {
   
        Set<Integer> s = new HashSet<>();
        for (int c : candyType) {
   
            s.add(c);
        }
        return Math.min(candyType.length >> 1, s.size());
    }
}

下接:【题解】—— LeetCode一周小结23


相关文章
|
1月前
|
索引
|
1月前
|
测试技术 索引
【题解】—— LeetCode一周小结40
LeetCode每日一道一周小结40
|
2月前
|
机器人
|
2月前
|
算法
【题解】—— LeetCode一周小结36
LeetCode每日一道一周小结36