3445.奇偶频次间的最大差值II

目标

给你一个字符串 s 和一个整数 k 。请你找出 s 的子字符串 subs 中两个字符的出现频次之间的 最大 差值,freq[a] - freq[b] ,其中:

  • subs 的长度 至少 为 k 。
  • 字符 a 在 subs 中出现奇数次。
  • 字符 b 在 subs 中出现偶数次。

返回 最大 差值。

注意 ,subs 可以包含超过 2 个 互不相同 的字符。.

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

示例 1:

输入:s = "12233", k = 4
输出:-1
解释:
对于子字符串 "12233" ,'1' 的出现次数是 1 ,'3' 的出现次数是 2 。差值是 1 - 2 = -1 。

示例 2:

输入:s = "1122211", k = 3
输出:1
解释:
对于子字符串 "11222" ,'2' 的出现次数是 3 ,'1' 的出现次数是 2 。差值是 3 - 2 = 1 。

示例 3:

输入:s = "110", k = 3
输出:-1

说明:

  • 3 <= s.length <= 3 * 10^4
  • s 仅由数字 '0' 到 '4' 组成。
  • 输入保证至少存在一个子字符串是由一个出现奇数次的字符和一个出现偶数次的字符组成。
  • 1 <= k <= s.length

思路

有一个字符串 s 仅由 0 ~ 4 组成,求其长度至少为 k 的子串中,3442_奇偶频次间的最大差值I 的最大值。

// todo

代码

性能

1857.有向图中最大颜色值

目标

给你一个 有向图 ,它含有 n 个节点和 m 条边。节点编号从 0 到 n - 1 。

给你一个字符串 colors ,其中 colors[i] 是小写英文字母,表示图中第 i 个节点的 颜色 (下标从 0 开始)。同时给你一个二维数组 edges ,其中 edges[j] = [aj, bj] 表示从节点 aj 到节点 bj 有一条 有向边 。

图中一条有效 路径 是一个点序列 x1 -> x2 -> x3 -> ... -> xk ,对于所有 1 <= i < k ,从 xi 到 xi+1 在图中有一条有向边。路径的 颜色值 是路径中 出现次数最多 颜色的节点数目。

请你返回给定图中有效路径里面的 最大颜色值 。如果图中含有环,请返回 -1 。

示例 1:

输入:colors = "abaca", edges = [[0,1],[0,2],[2,3],[3,4]]
输出:3
解释:路径 0 -> 2 -> 3 -> 4 含有 3 个颜色为 "a" 的节点(上图中的红色节点)。

示例 2:

输入:colors = "a", edges = [[0,0]]
输出:-1
解释:从 0 到 0 有一个环。

说明:

  • n == colors.length
  • m == edges.length
  • 1 <= n <= 10^5
  • 0 <= m <= 10^5
  • colors 只含有小写英文字母。
  • 0 <= aj, bj < n

思路

// 今天没空做了 todo

代码

性能

3068.最大节点价值之和

目标

给你一棵 n 个节点的 无向 树,节点从 0 到 n - 1 编号。树以长度为 n - 1 下标从 0 开始的二维整数数组 edges 的形式给你,其中 edges[i] = [ui, vi] 表示树中节点 ui 和 vi 之间有一条边。同时给你一个 正 整数 k 和一个长度为 n 下标从 0 开始的 非负 整数数组 nums ,其中 nums[i] 表示节点 i 的 价值 。

Alice 想 最大化 树中所有节点价值之和。为了实现这一目标,Alice 可以执行以下操作 任意 次(包括 0 次):

  • 选择连接节点 u 和 v 的边 [u, v] ,并将它们的值更新为:
    • nums[u] = nums[u] XOR k
    • nums[v] = nums[v] XOR k

请你返回 Alice 通过执行以上操作 任意次 后,可以得到所有节点 价值之和 的 最大值 。

示例 1:

输入:nums = [1,2,1], k = 3, edges = [[0,1],[0,2]]
输出:6
解释:Alice 可以通过一次操作得到最大价值和 6 :
- 选择边 [0,2] 。nums[0] 和 nums[2] 都变为:1 XOR 3 = 2 ,数组 nums 变为:[1,2,1] -> [2,2,2] 。
所有节点价值之和为 2 + 2 + 2 = 6 。
6 是可以得到最大的价值之和。

示例 2:

输入:nums = [2,3], k = 7, edges = [[0,1]]
输出:9
解释:Alice 可以通过一次操作得到最大和 9 :
- 选择边 [0,1] 。nums[0] 变为:2 XOR 7 = 5 ,nums[1] 变为:3 XOR 7 = 4 ,数组 nums 变为:[2,3] -> [5,4] 。
所有节点价值之和为 5 + 4 = 9 。
9 是可以得到最大的价值之和。

示例 3:

输入:nums = [7,7,7,7,7,7], k = 3, edges = [[0,1],[0,2],[0,3],[0,4],[0,5]]
输出:42
解释:Alice 不需要执行任何操作,就可以得到最大价值之和 42 。

说明:

  • 2 <= n == nums.length <= 2 * 10^4
  • 1 <= k <= 10^9
  • 0 <= nums[i] <= 10^9
  • edges.length == n - 1
  • edges[i].length == 2
  • 0 <= edges[i][0], edges[i][1] <= n - 1
  • 输入保证 edges 构成一棵合法的树。

思路

// todo

代码

性能

3343.统计平衡排列的数目

目标

给你一个字符串 num 。如果一个数字字符串的奇数位下标的数字之和与偶数位下标的数字之和相等,那么我们称这个数字字符串是 平衡的 。

请你返回 num 不同排列 中,平衡 字符串的数目。

由于答案可能很大,请你将答案对 10^9 + 7 取余 后返回。

一个字符串的 排列 指的是将字符串中的字符打乱顺序后连接得到的字符串。

示例 1:

输入:num = "123"
输出:2
解释:
num 的不同排列包括: "123" ,"132" ,"213" ,"231" ,"312" 和 "321" 。
它们之中,"132" 和 "231" 是平衡的。所以答案为 2 。

示例 2:

输入:num = "112"
输出:1
解释:
num 的不同排列包括:"112" ,"121" 和 "211" 。
只有 "121" 是平衡的。所以答案为 1 。

示例 3:

输入:num = "12345"
输出:0
解释:
num 的所有排列都是不平衡的。所以答案为 0 。

说明:

  • 2 <= num.length <= 80
  • num 中的字符只包含数字 '0' 到 '9' 。

思路

//todo

代码

性能

2338.统计理想数组的数目

目标

给你两个整数 n 和 maxValue ,用于描述一个 理想数组 。

对于下标从 0 开始、长度为 n 的整数数组 arr ,如果满足以下条件,则认为该数组是一个 理想数组 :

  • 每个 arr[i] 都是从 1 到 maxValue 范围内的一个值,其中 0 <= i < n 。
  • 每个 arr[i] 都可以被 arr[i - 1] 整除,其中 0 < i < n 。

返回长度为 n 的 不同 理想数组的数目。由于答案可能很大,返回对 10^9 + 7 取余的结果。

示例 1:

输入:n = 2, maxValue = 5
输出:10
解释:存在以下理想数组:
- 以 1 开头的数组(5 个):[1,1]、[1,2]、[1,3]、[1,4]、[1,5]
- 以 2 开头的数组(2 个):[2,2]、[2,4]
- 以 3 开头的数组(1 个):[3,3]
- 以 4 开头的数组(1 个):[4,4]
- 以 5 开头的数组(1 个):[5,5]
共计 5 + 2 + 1 + 1 + 1 = 10 个不同理想数组。

示例 2:

输入:n = 5, maxValue = 3
输出:11
解释:存在以下理想数组:
- 以 1 开头的数组(9 个):
   - 不含其他不同值(1 个):[1,1,1,1,1] 
   - 含一个不同值 2(4 个):[1,1,1,1,2], [1,1,1,2,2], [1,1,2,2,2], [1,2,2,2,2]
   - 含一个不同值 3(4 个):[1,1,1,1,3], [1,1,1,3,3], [1,1,3,3,3], [1,3,3,3,3]
- 以 2 开头的数组(1 个):[2,2,2,2,2]
- 以 3 开头的数组(1 个):[3,3,3,3,3]
共计 9 + 1 + 1 = 11 个不同理想数组。

说明:

  • 2 <= n <= 10^4
  • 1 <= maxValue <= 10^4

思路

//todo

代码

性能

2179.统计数组中好三元组数目

目标

给你两个下标从 0 开始且长度为 n 的整数数组 nums1 和 nums2 ,两者都是 [0, 1, ..., n - 1] 的 排列 。

好三元组 指的是 3 个 互不相同 的值,且它们在数组 nums1 和 nums2 中出现顺序保持一致。换句话说,如果我们将 pos1v 记为值 v 在 nums1 中出现的位置,pos2v 为值 v 在 nums2 中的位置,那么一个好三元组定义为 0 <= x, y, z <= n - 1 ,且 pos1x < pos1y < pos1z 和 pos2x < pos2y < pos2z 都成立的 (x, y, z) 。

请你返回好三元组的 总数目 。

示例 1:

输入:nums1 = [2,0,1,3], nums2 = [0,1,2,3]
输出:1
解释:
总共有 4 个三元组 (x,y,z) 满足 pos1x < pos1y < pos1z ,分别是 (2,0,1) ,(2,0,3) ,(2,1,3) 和 (0,1,3) 。
这些三元组中,只有 (0,1,3) 满足 pos2x < pos2y < pos2z 。所以只有 1 个好三元组。

示例 2:

输入:nums1 = [4,0,1,3,2], nums2 = [4,1,0,2,3]
输出:4
解释:总共有 4 个好三元组 (4,0,3) ,(4,0,2) ,(4,1,3) 和 (4,1,2) 。

说明:

  • n == nums1.length == nums2.length
  • 3 <= n <= 10^5
  • 0 <= nums1[i], nums2[i] <= n - 1
  • nums1 和 nums2 是 [0, 1, ..., n - 1] 的排列。

提示:

  • For every value y, how can you find the number of values x (0 ≤ x, y ≤ n - 1) such that x appears before y in both of the arrays?
  • Similarly, for every value y, try finding the number of values z (0 ≤ y, z ≤ n - 1) such that z appears after y in both of the arrays.
  • Now, for every value y, count the number of good triplets that can be formed if y is considered as the middle element.

思路

有两个 0 ~ n - 1 的排列,好三元组指这两个排列的公共子序列,求好三元组的总数目。

// todo

代码

性能

368.最大整除子集

目标

给你一个由 无重复 正整数组成的集合 nums ,请你找出并返回其中最大的整除子集 answer ,子集中每一元素对 (answer[i], answer[j]) 都应当满足:

  • answer[i] % answer[j] == 0 ,或
  • answer[j] % answer[i] == 0

如果存在多个有效解子集,返回其中任何一个均可。

示例 1:

输入:nums = [1,2,3]
输出:[1,2]
解释:[1,3] 也会被视为正确答案。

示例 2:

输入:nums = [1,2,4,8]
输出:[1,2,4,8]

说明:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 2 * 10^9
  • nums 中的所有整数 互不相同

思路

// todo

代码

性能

2140.解决智力问题

目标

给你一个下标从 0 开始的二维整数数组 questions ,其中 questions[i] = [pointsi, brainpoweri] 。

这个数组表示一场考试里的一系列题目,你需要 按顺序 (也就是从问题 0 开始依次解决),针对每个问题选择 解决 或者 跳过 操作。解决问题 i 将让你 获得 pointsi 的分数,但是你将 无法 解决接下来的 brainpoweri 个问题(即只能跳过接下来的 brainpoweri 个问题)。如果你跳过问题 i ,你可以对下一个问题决定使用哪种操作。

比方说,给你 questions = [[3, 2], [4, 3], [4, 4], [2, 5]] :

  • 如果问题 0 被解决了, 那么你可以获得 3 分,但你不能解决问题 1 和 2 。
  • 如果你跳过问题 0 ,且解决问题 1 ,你将获得 4 分但是不能解决问题 2 和 3 。

请你返回这场考试里你能获得的 最高 分数。

示例 1:

输入:questions = [[3,2],[4,3],[4,4],[2,5]]
输出:5
解释:解决问题 0 和 3 得到最高分。
- 解决问题 0 :获得 3 分,但接下来 2 个问题都不能解决。
- 不能解决问题 1 和 2
- 解决问题 3 :获得 2 分
总得分为:3 + 2 = 5 。没有别的办法获得 5 分或者多于 5 分。

示例 2:

输入:questions = [[1,1],[2,2],[3,3],[4,4],[5,5]]
输出:7
解释:解决问题 1 和 4 得到最高分。
- 跳过问题 0
- 解决问题 1 :获得 2 分,但接下来 2 个问题都不能解决。
- 不能解决问题 2 和 3
- 解决问题 4 :获得 5 分
总得分为:2 + 5 = 7 。没有别的办法获得 7 分或者多于 7 分。

说明:

  • 1 <= questions.length <= 10^5
  • questions[i].length == 2
  • 1 <= pointsi, brainpoweri <= 10^5

思路

有一个二维数组 questions 表示一场考试里的一系列题目,questions[i][0] 表示解决第 i 题能获得的分数,questions[i][1] 表示解决该题需要消耗的脑力,即解决了第 i 题后,i 后面的 questions[i][1] 个题目都无法解决。返回在该场考试所能获得的最高分。

这个题有许多值得思考的地方,有空整理一下。//todo

代码


/**
 * @date 2025-04-01 8:47
 */
public class MostPoints2140 {

    public long mostPoints(int[][] questions) {
        int n = questions.length;
        long[] dp = new long[n + 1];
        for (int i = n - 1; i >= 0; i--) {
            int j = Math.min(i + questions[i][1] + 1, n);
            dp[i] = Math.max(dp[i + 1], dp[j] + questions[i][0]);
        }
        return dp[0];
    }

}

性能

2360.图中的最长环

目标

给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,其中每个节点 至多 有一条出边。

图用一个大小为 n 下标从 0 开始的数组 edges 表示,节点 i 到节点 edges[i] 之间有一条有向边。如果节点 i 没有出边,那么 edges[i] == -1 。

请你返回图中的 最长 环,如果没有任何环,请返回 -1 。

一个环指的是起点和终点是 同一个 节点的路径。

示例 1:

输入:edges = [3,3,4,2,3]
输出去:3
解释:图中的最长环是:2 -> 4 -> 3 -> 2 。
这个环的长度为 3 ,所以返回 3 。

示例 2:

输入:edges = [2,-1,3,1]
输出:-1
解释:图中没有任何环。

说明:

  • n == edges.length
  • 2 <= n <= 10^5
  • -1 <= edges[i] < n
  • edges[i] != i

思路

//todo

代码

性能

2612.最少翻转操作数

目标

给你一个整数 n 和一个在范围 [0, n - 1] 以内的整数 p ,它们表示一个长度为 n 且下标从 0 开始的数组 arr ,数组中除了下标为 p 处是 1 以外,其他所有数都是 0 。

同时给你一个整数数组 banned ,它包含数组中的一些位置。banned 中第 i 个位置表示 arr[banned[i]] = 0 ,题目保证 banned[i] != p 。

你可以对 arr 进行 若干次 操作。一次操作中,你选择大小为 k 的一个 子数组 ,并将它 翻转 。在任何一次翻转操作后,你都需要确保 arr 中唯一的 1 不会到达任何 banned 中的位置。换句话说,arr[banned[i]] 始终 保持 0 。

请你返回一个数组 ans ,对于 [0, n - 1] 之间的任意下标 i ,ans[i] 是将 1 放到位置 i 处的 最少 翻转操作次数,如果无法放到位置 i 处,此数为 -1 。

  • 子数组 指的是一个数组里一段连续 非空 的元素序列。
  • 对于所有的 i ,ans[i] 相互之间独立计算。
  • 将一个数组中的元素 翻转 指的是将数组中的值变成 相反顺序 。

示例 1:

输入:n = 4, p = 0, banned = [1,2], k = 4
输出:[0,-1,-1,1]
解释:k = 4,所以只有一种可行的翻转操作,就是将整个数组翻转。一开始 1 在位置 0 处,所以将它翻转到位置 0 处需要的操作数为 0 。
我们不能将 1 翻转到 banned 中的位置,所以位置 1 和 2 处的答案都是 -1 。
通过一次翻转操作,可以将 1 放到位置 3 处,所以位置 3 的答案是 1 。

示例 2:

输入:n = 5, p = 0, banned = [2,4], k = 3
输出:[0,-1,-1,-1,-1]
解释:这个例子中 1 一开始在位置 0 处,所以此下标的答案为 0 。
翻转的子数组长度为 k = 3 ,1 此时在位置 0 处,所以我们可以翻转子数组 [0, 2],但翻转后的下标 2 在 banned 中,所以不能执行此操作。
由于 1 没法离开位置 0 ,所以其他位置的答案都是 -1 。

示例 3:

输入:n = 4, p = 2, banned = [0,1,3], k = 1
输出:[-1,-1,0,-1]
解释:这个例子中,我们只能对长度为 1 的子数组执行翻转操作,所以 1 无法离开初始位置。

说明:

  • 1 <= n <= 10^5
  • 0 <= p <= n - 1
  • 0 <= banned.length <= n - 1
  • 0 <= banned[i] <= n - 1
  • 1 <= k <= n
  • banned[i] != p
  • banned 中的值 互不相同 。

思路

// todo

代码

性能