day52(补)

本文详细解析了如何使用动态规划解决LeetCode上的最长递增子序列问题,介绍了dp数组的定义、状态转移方程、初始化步骤和遍历顺序,以及如何通过代码实现。

300.最长递增子序列

力扣题目链接(opens new window)

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

示例 1:

  • 输入:nums = [10,9,2,5,3,7,101,18]
  • 输出:4
  • 解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

示例 2:

  • 输入:nums = [0,1,0,3,2,3]
  • 输出:4

示例 3:

  • 输入:nums = [7,7,7,7,7,7,7]
  • 输出:1

提示:

  • 1 <= nums.length <= 2500
  • -10^4 <= nums[i] <= 104

#算法公开课

《代码随想录》算法视频公开课 (opens new window)::动态规划之子序列问题,元素不连续!| LeetCode:300.最长递增子序列 (opens new window),相信结合视频再看本篇题解,更有助于大家对本题的理解

#思路

首先通过本题大家要明确什么是子序列,“子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序”。

本题也是代码随想录中子序列问题的第一题,如果没接触过这种题目的话,本题还是很难的,甚至想暴力去搜索也不知道怎么搜。 子序列问题是动态规划解决的经典问题,当前下标i的递增子序列长度,其实和i之前的下表j的子序列长度有关系,那又是什么样的关系呢。

接下来,我们依然用动规五部曲来详细分析一波:

  1. dp[i]的定义

本题中,正确定义dp数组的含义十分重要。

dp[i]表示i之前包括i的以nums[i]结尾的最长递增子序列的长度

为什么一定表示 “以nums[i]结尾的最长递增子序” ,因为我们在 做 递增比较的时候,如果比较 nums[j] 和 nums[i] 的大小,那么两个递增子序列一定分别以nums[j]为结尾 和 nums[i]为结尾, 要不然这个比较就没有意义了,不是尾部元素的比较那么 如何算递增呢。

  1. 状态转移方程

位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 + 1 的最大值。

所以:if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);

注意这里不是要dp[i] 与 dp[j] + 1进行比较,而是我们要取dp[j] + 1的最大值

  1. dp[i]的初始化

每一个i,对应的dp[i](即最长递增子序列)起始大小至少都是1.

  1. 确定遍历顺序

dp[i] 是有0到i-1各个位置的最长递增子序列 推导而来,那么遍历i一定是从前向后遍历。

j其实就是遍历0到i-1,那么是从前到后,还是从后到前遍历都无所谓,只要吧 0 到 i-1 的元素都遍历了就行了。 所以默认习惯 从前向后遍历。

遍历i的循环在外层,遍历j则在内层,代码如下:

for (int i = 1; i < nums.size(); i++) {
    for (int j = 0; j < i; j++) {
        if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
    }
    if (dp[i] > result) result = dp[i]; // 取长的子序列
}

1
2
3
4
5
6

  1. 举例推导dp数组

输入:[0,1,0,3,2],dp数组的变化如下:

300.最长上升子序列

如果代码写出来,但一直AC不了,那么就把dp数组打印出来,看看对不对!

以上五部分析完毕,C++代码如下:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        if (nums.size() <= 1) return nums.size();
        vector<int> dp(nums.size(), 1);
        int result = 0;
        for (int i = 1; i < nums.size(); i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) dp[i] = max(dp[i], dp[j] + 1);
            }
            if (dp[i] > result) result = dp[i]; // 取长的子序列
        }
        return result;
    }
};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

  • 时间复杂度: O(n^2)
  • 空间复杂度: O(n)

#总结

本题最关键的是要想到dp[i]由哪些状态可以推出来,并取最大值,那么很自然就能想到递推公式:dp[i] = max(dp[i], dp[j] + 1);

子序列问题是动态规划的一个重要系列,本题算是入门题目,好戏刚刚开始!

#其他语言版本

#Java:

class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int res = 0;
        Arrays.fill(dp, 1);
        for (int i = 1; i < dp.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
                res = Math.max(res, dp[i]);
            }
        }
        return res;
    }
}
This field follows the syntax of cron (with minor differences). Specifically, each line consists of 5 fields separated by TAB or whitespace: MINUTE HOUR DOM MONTH DOW MINUTE Minutes within the hour (0–59) HOUR The hour of the day (0–23) DOM The day of the month (1–31) MONTH The month (1–12) DOW The day of the week (0–7) where 0 and 7 are Sunday. To specify multiple values for one field, the following operators are available. In the order of precedence, * specifies all valid values M-N specifies a range of values M-N/X or */X steps by intervals of X through the specified range or whole valid range A,B,...,Z enumerates multiple values To allow periodically scheduled tasks to produce even load on the system, the symbol H (for “hash”) should be used wherever possible. For example, using 0 0 * * * for a dozen daily jobs will cause a large spike at midnight. In contrast, using H H * * * would still execute each job once a day, but not all at the same time, better using limited resources. The H symbol can be used with a range. For example, H H(0-7) * * * means some time between 12:00 AM (midnight) to 7:59 AM. You can also use step intervals with H, with or without ranges. The H symbol can be thought of as a random value over a range, but it actually is a hash of the job name, not a random function, so that the value remains stable for any given project. Beware that for the day of month field, short cycles such as */3 or H/3 will not work consistently near the end of most months, due to variable month lengths. For example, */3 will run on the 1st, 4th, …31st days of a long month, then again the next day of the next month. Hashes are always chosen in the 1-28 range, so H/3 will produce a gap between runs of between 3 and 6 days at the end of a month. (Longer cycles will also have inconsistent lengths but the effect may be relatively less noticeable.) Empty lines and lines that start with # will be ignored as comments. In addition, @yearly, @annually, @monthly, @weekly, @daily, @midnight, and @hourly are supported as convenient aliases. These use the hash system for automatic balancing. For example, @hourly is the same as H * * * * and could mean at any time during the hour. @midnight actually means some time between 12:00 AM and 2:59 AM. Examples: # Every fifteen minutes (perhaps at :07, :22, :37, :52): H/15 * * * * # Every ten minutes in the first half of every hour (three times, perhaps at :04, :14, :24): H(0-29)/10 * * * * # Once every two hours at 45 minutes past the hour starting at 9:45 AM and finishing at 3:45 PM every weekday: 45 9-16/2 * * 1-5 # Once in every two hour slot between 8 AM and 4 PM every weekday (perhaps at 9:38 AM, 11:38 AM, 1:38 PM, 3:38 PM): H H(8-15)/2 * * 1-5 # Once a day on the 1st and 15th of every month except December: H H 1,15 1-11 * Time zone specification Periodic tasks are normally executed at the scheduled time in the time zone of the Jenkins master JVM (currently America/Los_Angeles). This behavior can optionally be changed by specifying an alternative time zone in the first line of the field. Time zone specification starts with TZ=, followed by the ID of a time zone. Complete example of a schedule with a time zone specification: TZ=Europe/London # This job needs to be run in the morning, London time H 8 * * * # Butlers do not have a five o'clock, so we run the job again H(0-30) 17 * * *
12-17
你提供的内容是关于 **Jenkins 的定时任务(cron)语法说明**,用于配置周期性构建任务的时间规则。Jenkins 的 cron 语法与标准的 Unix cron 类似,但有一些扩展和优化,比如使用 `H`(Hash)来均衡负载。 --- ### ✅ Jenkins Cron 语法结构 每一行表示一个定时规则,由 5 个字段组成,字段之间使用 **空格或 Tab** 分隔: ``` MINUTE HOUR DAY_OF_MONTH MONTH DAY_OF_WEEK ``` | 字段名 | 范围 | 说明 | |----------------|------------------|--------------------------| | MINUTE | `0–59` | 小时内的分钟 | | HOUR | `0–23` | 一天中的小时 | | DAY_OF_MONTH | `1–31` | 月份中的日期 | | MONTH | `1–12` | 月份 | | DAY_OF_WEEK | `0–7`(0 和 7 表示星期日) | 一周中的第几天 | --- ### ✅ 操作符说明 | 操作符 | 说明 | 示例 | |------------|------------------------------|---------------------------------| | `*` | 所有可能的值 | `* * * * *` 表示每分钟执行一次 | | `M-N` | 某个范围内的值 | `9-17 * * * *` 表示每小时的 9 点到 17 点之间每小时执行 | | `M-N/X` 或 `*/X` | 按 X 步长遍历范围或整个范围 | `H/15 * * * *` 丁时间每隔 15 分钟运行一次 | | `A,B,...Z` | 枚举多个值 | `1,15 * * * *` 表示每月 1 日和 15 日执行 | --- ### ✅ `H`(Hash)的使用 - `H` 是 Jenkins 特有的符号,用于**随机但稳定**地分配时间,避免系统负载峰值。 - 实际是基于 job 名的哈希值,因此对同一个 job 来说是稳定的。 #### 示例: | 表达式 | 含义说明 | |---------------------|-----------------------------------------------| | `H * * * *` | 每小时的某个随机分钟执行(每小时执行一次) | | `H H * * *` | 每天的某个随机时间执行(每天执行一次) | | `H H(0-7) * * *` | 每天早上 0 到 7 点之间的一个随机时间执行 | | `H H 1,15 * *` | 每月 1 日和 15 日的某个随机时间执行 | --- ### ✅ 时间区间和步长注意事项 - `H/3` 在 `DAY_OF_MONTH` 字段中会从 1~28 中选择,避免月末天数不一致导致的问题。 - 使用 `*/3` 可能导致月末任务执行时间不一致,推荐使用 `H/3` 更稳定。 --- ### ✅ Jenkins 支持的快捷别名 | 别名 | 含义等价于 | 说明 | |------------|---------------------|-------------------------------| | `@yearly` | `H H 1 1 *` | 每年一次 | | `@annually`| `H H 1 1 *` | 同上 | | `@monthly` | `H H 1 * *` | 每月一次 | | `@weekly` | `H H * * 0` | 每周一次 | | `@daily` | `H H * * *` | 每天一次 | | `@midnight`| `H H * * *` | 每天凌晨(00:00 ~ 02:59) | | `@hourly` | `H * * * *` | 每小时一次 | --- ### ✅ 示例解析 ```cron # 每15分钟执行一次(如 :07, :22, :37, :52) H/15 * * * * # 每小时前30分钟内,每10分钟执行一次(如 :04, :14, :24) H(0-29)/10 * * * * # 每个工作日 9:45 AM 到 3:45 PM 之间,每两小时执行一次 45 9-16/2 * * 1-5 # 每个工作日 8AM 到 4PM 之间,每两小时执行一次(时间随机) H H(8-15)/2 * * 1-5 # 每月 1 号和 15 号执行(不包括 12 月) H H 1,15 1-11 * ``` --- ### ✅ 时区设置 默认使用 Jenkins 主机的 JVM 时区(如 `America/Los_Angeles`),也可以在第一行指定时区: ```cron TZ=Europe/London # 伦敦时间早上 8 点执行 H 8 * * * # 下午 5 点前半小时执行 H(0-30) 17 * * * ``` --- ```bash # 示例:每小时执行一次 H * * * * ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值