跳至主要內容

2777. 日期范围生成器 🔒


2777. 日期范围生成器 🔒

🟠   🔗 力扣open in new window LeetCodeopen in new window

题目

Given a start date start, an end date end, and a positive integer step, return a generator object that yields dates in the range from start to end inclusive.

The value of step indicates the number of days between consecutive yielded values.

All yielded dates must be in the string format YYYY-MM-DD.

Example 1:

Input: start = "2023-04-01", end = "2023-04-04", step = 1

Output: ["2023-04-01","2023-04-02","2023-04-03","2023-04-04"]

Explanation:

const g = dateRangeGenerator(start, end, step);
g.next().value; // '2023-04-01'
g.next().value; // '2023-04-02'
g.next().value; // '2023-04-03'
g.next().value; // '2023-04-04'

Example 2:

Input: start = "2023-04-10", end = "2023-04-20", step = 3

Output: ["2023-04-10","2023-04-13","2023-04-16","2023-04-19"]

Explanation:

const g = dateRangeGenerator(start, end, step);
g.next().value; // '2023-04-10'
g.next().value; // '2023-04-13'
g.next().value; // '2023-04-16'
g.next().value; // '2023-04-19'

Example 3:

Input: start = "2023-04-10", end = "2023-04-10", step = 1

Output: ["2023-04-10"]

Explanation:

const g = dateRangeGenerator(start, end, step);
g.next().value; // '2023-04-10'

Constraints:

  • new Date(start) <= new Date(end)
  • start and end dates are in the string format YYYY-MM-DD
  • 0 <= The difference in days between the start date and the end date <= 1500
  • 1 <= step <= 1000

题目大意

现给定起始日期 start 、结束日期 end 和正整数 step ,返回一个生成器对象,该生成器对象按照从 startend(包括 start 和 end )的范围生成日期。

step 的值表示连续生成的日期之间的天数间隔。

所有日期都以字符串格式 YYYY-MM-DD 表示。

示例 1:

输入: start = "2023-04-01", end = "2023-04-04", step = 1

输出:["2023-04-01","2023-04-02","2023-04-03","2023-04-04"]

解释:

const g = dateRangeGenerator(start, end, step);
g.next().value; // '2023-04-01'
g.next().value; // '2023-04-02'
g.next().value; // '2023-04-03'
g.next().value; // '2023-04-04'

示例 2:

输入: start = "2023-04-10", end = "2023-04-20", step = 3

输出:["2023-04-10","2023-04-13","2023-04-16","2023-04-19"]

解释:

const g = dateRangeGenerator(start, end, step);
g.next().value; // '2023-04-10'
g.next().value; // '2023-04-13'
g.next().value; // '2023-04-16'
g.next().value; // '2023-04-19'

示例 3:

输入: start = "2023-04-10", end = "2023-04-10", step = 1

输出:["2023-04-10"]

解释:

const g = dateRangeGenerator(start, end, step);
g.next().value; // '2023-04-10'

提示:

  • new Date(start) <= new Date(end)
  • startend 的日期格式是 YYYY-MM-DD
  • 0 <= 结束日期与开始日期之间的天数差 <= 1500
  • 1 <= step <= 1000

解题思路

  1. 生成器函数: 生成器函数可以通过 function* 声明来创建,它允许在迭代过程中暂停并返回一个值。每次调用 next() 时,生成器会返回下一个日期。

  2. 生成器逻辑:

    • currentDate 是从 start 日期创建的 Date 对象,用于存储当前日期。
    • endDateend 日期的 Date 对象,表示结束日期。
    • step 表示从当前日期到下一个日期的天数差,需要使用 Date 对象的 setDate() 方法来增加或减少天数。
    • 生成器通过 while (currentDate <= endDate) 循环生成日期,直到 currentDate 超过 endDate
    • 每次循环中,生成器返回当前日期(格式化后的字符串),然后将 currentDate 增加 step 天。
  3. 日期格式化: 使用 toISOString() 方法来获取标准的 ISO 格式日期(例如:2024-11-04T00:00:00.000Z),然后从中提取 YYYY-MM-DD 部分。

复杂度分析

  • 时间复杂度O(n),其中 n 是生成的日期数,每次调用 next() 时,都会执行一次日期计算。
  • 空间复杂度O(1),生成器是惰性求值的,不会在内存中存储所有的日期,空间复杂度是常数级别。

代码

/**
 * @param {string} start
 * @param {string} end
 * @param {number} step
 * @return {Generator}
 */
var dateRangeGenerator = function* (start, end, step) {
	const curDate = new Date(start),
		endDate = new Date(end);

	// 生成日期直到超出结束日期
	while (curDate <= endDate) {
		// 使用 toISOString 提取 YYYY-MM-DD 格式
		yield curDate.toISOString().split('T')[0];

		// 设置新的日期
		curDate.setDate(curDate.getDate() + step);
	}
};