Spurs

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:

A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

这不是我们小时候玩的跳棋,所以我理解错了题意.所谓正确题意是,如第一个例子:
A[0] = 2, 代表 index = 1, 2 的元素我们都可以跳到(我原来以为得必须跳到 index = 2 的位置呢). 我们把能达到的最远索引保存在变量reach中. A[1] = 3, A[2] = 1, 那么选最大的, 则 reach = i + A[i] = 1 + 3.

说是贪心法.
精简的意思就是:
reach 是前沿阵地位置, i 是后方补给当前所在位置, 补给只在 reach 所定的安全区域逐步前行, i 能否到达数组最后一个元素, 完全取决于 reach 所能到达的位置. 但 i 在前行的过程中, 符合条件的话可以更新 reach. 有时候,虽然 i 还没到达数组最后元素, 但当前的reach >= n - 1了, i 就不需要向前走了(循环被 break), 因为reach已经表明共产主义肯定能实现, i 显然就没有向下走的必要了.

人家想法,自己代码:
牛就牛在这想法是\(O(n)\)的,而笨想法是\(O(n^2)\)的.
\(O(n)\) time, \(O(1)\) extra space.

bool canJump(vector<int>& A) {
	const int n = A.size();

	int i = 0;
	// 扫描reach范围内, i + A[i] 所能到达的最远位置.
	// 若能超过当前reach,则更新reach.
	for (int reach = 0; i < n && i <= reach; i++) {
		reach = max(i + A[i], reach);
		if (reach >= n - 1)
			return true;
	}
	// 2个事能导致退出循环, 既上面的循环条件
	// 不等于n, 只能因为 reach < i, reach 鞭长莫及了
	return i == n;
}
posted on 2017-08-26 17:00  英雄与侠义的化身  阅读(114)  评论(0编辑  收藏  举报