leetcode 45. 跳跃游戏 II

题意

给数组,初始在0号位置,可以跳\(nums[0]\) 步,最少多少次跳到最后

  • \(1 \leq nums.length \leq 10^4\)
  • \(0\leq nums[i]\leq 1000\)

解法1

暴力,复杂度是 \(values\times length\)\(1e7\) 不会超时

int t[N];
int jump(vector<int> &nums)
{
	int n = nums.size();
	for (int i = 0; i < n; i++)
		t[i] = 1e9;
	t[0] = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = min(i + 1, n - 1); j <= min(n - 1, i + nums[i]); j++)
		{
			t[j] = min(t[i] + 1, t[j]);
		}
	}
	return t[n - 1];
}

解法2

\([2,3,1,2,4,2,3]\) 为例,当前在0位置,一步可以跳到\(3,1\),两步最远可以是先跳到3,再跳到4,下标是0->1->4,

那么如果贪心的考虑每次跳两步最远的区域,那么第三步可选的区域就更大,

举例来说,第一步如果选跳到下标1,那么第二步可以选择的区域是下标\([0,1,2,3,4]\)

如果第一步选择跳到下标2,那么第二步可以选择的区域是于下标\([0,1,2]\)

重点:两步能到达的区域大小不同,第三步能到达的区域大小一定也不同

所以选择能使下下步有更多选择的下一步

所以代码实现时遍历一遍nums,不过要动态维护一个边界end

比如说刚开始这个边界就是2,因为最远能跳到下标2

接下来遍历1到2,发现现在能到达的最远下标maxPos是4

在遍历到end时,step++,并且将end=maxPos

再继续从原本的end+1遍历到新的end

int jump(vector<int> &nums)
{
	int n = nums.size();
	int maxPos = 0, end = 0, step = 0;
	for (int i = 0; i < n - 1; i++)
	{
		maxPos = max(maxPos, i + nums[i]);
		if (i == end)
		{
			end = maxPos;
			step++;
		}
	}
	return step;
}
posted @ 2024-12-02 18:00  lulaalu  阅读(37)  评论(0)    收藏  举报