题目1

跳跃游戏ii 给你一个数组v v[i] 表示从i开始最多能跳几格,求到达n - 1下标的最少次数

思路: 我们设置一个变量right 来维护当前跳跃的范围,endd来维护当前可以到达的最大格子,ans 来记录答案

操作过程如下:

  • 每走到一个新的格子 判断当前格子在不在跳跃可达的范围内,如果不行的话 说明需要一次额外的跳跃,此时ans++, right = endd
  • 每走到一个新的格子 更新end = max(end, i + v[i]) 代码:
int n;
cin >> n;
vector<int> v(n);
for (int i = 0; i < n; i++) cin >> v[i];
 
int ans = 0, right = 0, endd = 0;
for (int i = 0 ; i < n; i++)
{
	endd = max(endd, i + v[i]);
	if (i == right)
	{
		if (i == endd)
		{
			cout << -1;
			return;
		}
		ans++;
		right = endd;
	}
}

题目2

浇水问题: 给你一个数组v 其中 v[i] 表示第i个地方有一个水管 浇水可以覆盖 求使得整个花园都能浇到水的最少水管数目 如果无法完全覆盖,返回-1

思路: 我们先创建一个新的数组right 其中right[i] 表示第i个位置开始 能到达的范围 例如:v[3] = 2 那么v[3] 可以覆盖 的范围 那么 right[1] = max(right[1], 5)

随后,这个问题就跟题目一一模一样了

代码:

int n;
cin >> n;
vector<int>v(n);
for (int i = 0; i < n; i++) cin >> v[i];
vector<int> right(n);
for (int i = 0; i < n; i++) right[i - v[i]] = max(right[i - v[i]], i + v[i]);
 
int ans = 0, curright = 0, nextright = 0;
for (int i = 0; i < n; i++)
{
	nextright = max(nextright, right[i]);
	if (i == curright)
	{
		if (i == nextright)
		{
			cout << -1;
			return;
		}
		ans++;
		curright = nextright;
	}
}
cout << ans;

题目3

题目4

题目5

题目6