3637.三段式数组I

目标

给你一个长度为 n 的整数数组 nums。

如果存在索引 0 < p < q < n − 1,使得数组满足以下条件,则称其为 三段式数组(trionic):

  • nums[0...p] 严格 递增,
  • nums[p...q] 严格 递减,
  • nums[q...n − 1] 严格 递增。

如果 nums 是三段式数组,返回 true;否则,返回 false。

示例 1:

输入: nums = [1,3,5,4,2,6]
输出: true
解释:
选择 p = 2, q = 4:
nums[0...2] = [1, 3, 5] 严格递增 (1 < 3 < 5)。
nums[2...4] = [5, 4, 2] 严格递减 (5 > 4 > 2)。
nums[4...5] = [2, 6] 严格递增 (2 < 6)。

示例 2:

输入: nums = [2,1,3]
输出: false
解释:
无法选出能使数组满足三段式要求的 p 和 q 。

说明:

  • 3 <= n <= 100
  • -1000 <= nums[i] <= 1000

思路

判断数组是否是三段式数组,所谓三段式数组指第一段严格递增,第二段严格递减,第三段严格递增。

根据题意模拟,判断数组拐弯的次数是否等于 2,注意第一段应该是严格递增的。

代码


/**
 * @date 2026-02-03 9:11
 */
public class IsTrionic3637 {

    public boolean isTrionic(int[] nums) {
        if (nums[0] >= nums[1]) {
            return false;
        }
        int n = nums.length;
        int cnt = 0;
        for (int i = 1; i < n - 1; i++) {
            if (nums[i] == nums[i + 1]) {
                return false;
            } else if (nums[i - 1] > nums[i] != nums[i] > nums[i + 1]) {
                cnt++;
            }
        }
        return cnt == 2;
    }

}

性能

3013.将数组分成最小总代价的子数组II

目标

给你一个下标从 0 开始长度为 n 的整数数组 nums 和两个 正 整数 k 和 dist 。

一个数组的 代价 是数组中的 第一个 元素。比方说,[1,2,3] 的代价为 1 ,[3,4,1] 的代价为 3 。

你需要将 nums 分割成 k 个 连续且互不相交 的子数组,满足 第二 个子数组与第 k 个子数组中第一个元素的下标距离 不超过 dist 。换句话说,如果你将 nums 分割成子数组 nums[0..(i1 - 1)], nums[i1..(i2 - 1)], ..., nums[ik-1..(n - 1)] ,那么它需要满足 ik-1 - i1 <= dist 。

请你返回这些子数组的 最小 总代价。

示例 1:

输入:nums = [1,3,2,6,4,2], k = 3, dist = 3
输出:5
解释:将数组分割成 3 个子数组的最优方案是:[1,3] ,[2,6,4] 和 [2] 。这是一个合法分割,因为 ik-1 - i1 等于 5 - 2 = 3 ,等于 dist 。总代价为 nums[0] + nums[2] + nums[5] ,也就是 1 + 2 + 2 = 5 。
5 是分割成 3 个子数组的最小总代价。

示例 2:

输入:nums = [10,1,2,2,2,1], k = 4, dist = 3
输出:15
解释:将数组分割成 4 个子数组的最优方案是:[10] ,[1] ,[2] 和 [2,2,1] 。这是一个合法分割,因为 ik-1 - i1 等于 3 - 1 = 2 ,小于 dist 。总代价为 nums[0] + nums[1] + nums[2] + nums[3] ,也就是 10 + 1 + 2 + 2 = 15 。
分割 [10] ,[1] ,[2,2,2] 和 [1] 不是一个合法分割,因为 ik-1 和 i1 的差为 5 - 1 = 4 ,大于 dist 。
15 是分割成 4 个子数组的最小总代价。

示例 3:

输入:nums = [10,8,18,9], k = 3, dist = 1
输出:36
解释:将数组分割成 4 个子数组的最优方案是:[10] ,[8] 和 [18,9] 。这是一个合法分割,因为 ik-1 - i1 等于 2 - 1 = 1 ,等于 dist 。总代价为 nums[0] + nums[1] + nums[2] ,也就是 10 + 8 + 18 = 36 。
分割 [10] ,[8,18] 和 [9] 不是一个合法分割,因为 ik-1 和 i1 的差为 3 - 1 = 2 ,大于 dist 。
36 是分割成 3 个子数组的最小总代价。

说明:

  • 3 <= n <= 10^5
  • 1 <= nums[i] <= 10^9
  • 3 <= k <= n
  • k - 2 <= dist <= n - 2

思路

定义数组的代价是其第一个元素值,有一个数组 nums,将其分割成 k 个连续且不相交的子数组,并且要求第 2 个子数组 与 第 k 个子数组的第一个元素的下标的距离不超过 dist,求子数组的最小总代价。

//todo

代码

性能

3010.将数组分成最小总代价的子数组I

目标

给你一个长度为 n 的整数数组 nums 。

一个数组的 代价 是它的 第一个 元素。比方说,[1,2,3] 的代价是 1 ,[3,4,1] 的代价是 3 。

你需要将 nums 分成 3 个 连续且没有交集 的子数组。

请你返回这些子数组的 最小 代价 总和 。

示例 1:

输入:nums = [1,2,3,12]
输出:6
解释:最佳分割成 3 个子数组的方案是:[1] ,[2] 和 [3,12] ,总代价为 1 + 2 + 3 = 6 。
其他得到 3 个子数组的方案是:
- [1] ,[2,3] 和 [12] ,总代价是 1 + 2 + 12 = 15 。
- [1,2] ,[3] 和 [12] ,总代价是 1 + 3 + 12 = 16 。

示例 2:

输入:nums = [5,4,3]
输出:12
解释:最佳分割成 3 个子数组的方案是:[5] ,[4] 和 [3] ,总代价为 5 + 4 + 3 = 12 。
12 是所有分割方案里的最小总代价。

示例 3:

输入:nums = [10,3,1,1]
输出:12
解释:最佳分割成 3 个子数组的方案是:[10,3] ,[1] 和 [1] ,总代价为 10 + 1 + 1 = 12 。
12 是所有分割方案里的最小总代价。

说明:

  • 3 <= n <= 50
  • 1 <= nums[i] <= 50

思路

定义数组的代价是其第一个元素值,有一个数组 nums,将其分割成 3 个连续且不相交子数组,求子数组的最小总代价。

第一个数组的代价是固定的,问题变成从 1 ~ n -1 选两个最小的元素值。可以排序后取前三个元素的和,或者使用双指针记录最小与次小元素。

代码


/**
 * @date 2026-02-02 9:49
 */
public class MinimumCost3010 {

    public int minimumCost(int[] nums) {
        int n = nums.length;
        int min1 = Integer.MAX_VALUE;
        int min2 = Integer.MAX_VALUE;
        for (int i = 1; i < n; i++) {
            if (nums[i] < min1) {
                min2 = min1;
                min1 = nums[i];
            } else if (nums[i] < min2) {
                min2 = nums[i];
            }
        }
        return nums[0] + min1 + min2;
    }
}

性能