跳至主要內容

2805. 自定义间隔 🔒


2805. 自定义间隔 🔒

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

题目

Function customInterval

Given a function fn, a number delay and a number period, return a number id.

customInterval is a function that should execute the provided function fn at intervals based on a linear pattern defined by the formula delay + period * count.

The count in the formula represents the number of times the interval has been executed starting from an initial value of 0.

Function customClearInterval

Given the id. id is the returned value from the function customInterval.

customClearInterval should stop executing provided function fn at intervals.

Note: The setTimeout and setInterval functions in Node.js return an object, not a number.

Example 1:

Input: delay = 50, period = 20, cancelTime = 225

Output: [50,120,210]

Explanation:

const t = performance.now();
const result = [];
const fn = () => {
	result.push(Math.floor(performance.now() - t));
};

const id = customInterval(fn, delay, period);

setTimeout(() => {
	customClearInterval(id);
}, 225);

50 + 20 * 0 = 50 // 50ms - 1st function call

50 + 20 * 1 = 70 // 50ms + 70ms = 120ms - 2nd function call

50 + 20 * 2 = 90 // 50ms + 70ms + 90ms = 210ms - 3rd function call

Example 2:

Input: delay = 20, period = 20, cancelTime = 150

Output: [20,60,120]

Explanation:

20 + 20 * 0 = 20 // 20ms - 1st function call

20 + 20 * 1 = 40 // 20ms + 40ms = 60ms - 2nd function call

20 + 20 * 2 = 60 // 20ms + 40ms + 60ms = 120ms - 3rd function call

Example 3:

Input: delay = 100, period = 200, cancelTime = 500

Output: [100,400]

Explanation:

100 + 200 * 0 = 100 // 100ms - 1st function call

100 + 200 * 1 = 300 // 100ms + 300ms = 400ms - 2nd function call

Constraints:

  • 20 <= delay, period <= 250
  • 20 <= cancelTime <= 1000

题目大意

函数 customInterval

给定一个函数 fn、一个数字 delay 和一个数字 period,返回一个数字 idcustomInterval 是一个函数,它应该根据公式 delay + period * count 在间隔中执行提供的函数 fn,公式中的 count 表示从初始值 0 开始执行间隔的次数。

函数 customClearInterval

给定 idid 是从函数 customInterval 返回的值。customClearInterval 应该停止在间隔中执行提供的函数 fn

注意: 在 Node.js 中,setTimeoutsetInterval 函数返回一个对象,而不是一个数字。

示例 1:

输入: delay = 50, period = 20, stopTime = 225

输出:[50,120,210]

解释:

const t = performance.now();
const result = [];
const fn = () => {
	result.push(Math.floor(performance.now() - t));
};

const id = customInterval(fn, delay, period);

setTimeout(() => {
	customClearInterval(id);
}, 225);

50 + 20 * 0 = 50 // 50ms - 第一个函数调用

50 + 20 * 1 = 70 // 50ms + 70ms = 120ms - 第二个函数调用

50 + 20 * 2 = 90 // 50ms + 70ms + 90ms = 210ms - 第三个函数调用

示例 2:

输入: delay = 20, period = 20, stopTime = 150

输出:[20,60,120]

解释:

20 + 20 * 0 = 20 // 20ms - 第一个函数调用

20 + 20 * 1 = 40 // 20ms + 40ms = 60ms - 第二个函数调用

20 + 20 * 2 = 60 // 20ms + 40ms + 60ms = 120ms - 第三个函数调用

示例 3:

输入: delay = 100, period = 200, stopTime = 500

输出:[100,400]

解释:

100 + 200 * 0 = 100 // 100ms - 第一个函数调用

100 + 200 * 1 = 300 // 100ms + 300ms = 400ms - 第二个函数调用

提示:

  • 20 <= delay, period <= 250
  • 20 <= stopTime <= 1000

解题思路

  1. 自定义定时函数 customInterval:

    • customInterval 接受 fndelayperiod
    • 初始化一个 count 变量为 0,用来记录调用次数。
    • 使用 setTimeout 设置初始延迟为 delay 毫秒。
    • 在每次调用时,计算下次延迟时间 delay + period * count
    • 继续递归调用 setTimeout,并更新 count
    • setTimeout 返回的 ID 用哈希表存储起来,以便后续可以清除该定时器。
    • 返回用于停止调用的唯一标识符 id,让 customClearInterval 可以根据这个 ID 停止定时器。
  2. 停止定时器 customClearInterval:

    • customClearInterval 使用 clearTimeout 清除相应的定时器,从而停止调用。

复杂度分析

  • 时间复杂度O(n),其中 n 是调用次数,取决于 stopTimeperiod,每次递归调用都会执行 setTimeout
  • 空间复杂度O(n),每次递归调用哈希表中都需要存储定时器 ID。

代码

const idMap = new Map();

/**
 * @param {Function} fn
 * @param {number} delay
 * @param {number} period
 * @return {number}
 */
var customClearInterval = function (fn, delay, period) {
	let count = 0;
	const next = () => {
		const curDelay = delay + period * count;
		idMap.set(
			id,
			setTimeout(() => {
				fn();
				count++;
				next();
			}, curDelay)
		);
	};
	const id = Data.now();
	next();
	return id;
};

/**
 * @param {number} id
 * @return {null}
 */
var customClearInterval = function (id) {
	if (idMap.has(id)) {
		clearTimeout(idMap.get(id));
		idMap.delete(id);
	}
};