leetcode刷题笔记605

写在前边

  • 今天的每日一题是个easy的,刚起床看了一眼觉得很简单,但是忙完别的事坐下来写的时候才发现领会错题意了。
    题目如下:
    假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。

示例 1:

输入: flowerbed = [1,0,0,0,1], n = 1
输出: True

示例 2:

输入: flowerbed = [1,0,0,0,1], n = 2
输出: False

注意:

数组内已种好的花不会违反种植规则。
输入的数组长度范围为 [1, 20000]。
n 是非负整数,且不会超过输入数组的大小。

我刚开始的想法很简单,就是将所有已经种好的花周围全部标记为不可种,把所有花标记完就好了
比如这样:
1 0 0 0 0 1
变成:
1 1 0 0 1 1
最后查一下为零的个数,将它与n相比就好了。
但是后来我发现这样是不行的。。。因为你额外种进去的花也是要遵守规则,不能挨着,而这种方法显然没考虑到。
后来我想到对于一种情况有多种解法,而我们只需要找到一种就可以,这符合DFS的想法,我就采用dfs的算法去解,具体思路为:
1.将位置place,数组,和要求种的数目n传给dfs函数
2.判断n是否<=0,如果是,返回true
3.判断位置place这里能不能种花,即他的前后是不是为空,如果可以,就种下,然后将下标为place的数组置为1,将place+1,–n和数组作为参数再次调用dfs
代码如下:

bool dfs(vector<int>& temp, int k, int& lastNum)
	{
		if (lastNum == 0)
		{
			return true;
		}
		for (int i = k; i < temp.size(); i++)
		{
			if (canPlace(temp, i))
			{
				temp[i] = 1;
				lastNum--;
				if (dfs(temp, i + 1, lastNum))
				{
					return true;
				}
                temp[i] = 0;
		        lastNum++;
			}
		}

		return false;

	}

我提交的时候发现runtime error,超时了,没办法我去看了题解,发现这道题的解法是一种贪心算法。。。贪心算法与DFS算法的唯一区别是,DFS算法考虑了在可以种花的地方种花与不种花两种情况,而贪心算法,正如上个博客说到的,是一种“鼠目寸光”的算法,在可以种花的地方一定种,这样最贪心的种,就能种到最多的花,而不用考虑在可以种花的地方不种花。
因为,如果在可以种花的地方不种花,最后都满足条件的话,那么在可以种花的地方种花,就一定能满足条件,换言之,如果这个地方可以种花,你种花了之后,没有满足条件,那么在这个地方不种花,一定不能满足条件。总结就是:“DFS算法有一半是用不到的,就是可以种花但是没种的那一半”。
可能有点绕口,但是我大概理解了这道题的想法,但是对于我上边说的,我不知道该如何证明,也不知道正确与否。DFS是走了所以情况的全集,走完之后发现,确实不行,贪心算法只是走了其中一条路径,但是如果这条路径不行,那么其他的更不行。大概是这个意思。但是比较抽象,我希望有更加数学化的解释。。。这样子凭空说,我觉得有点难以说服我,虽然我知道这道题是这么解的。
知道解法之后,这道题就简单很多了,代码如下:

class Solution {
public:
	bool canPlace(vector<int> temp, int k)
	{
		if (temp[k] == 1)
		{
			return false;
		}
		else
		{
			if (k == 0)
			{
				if (k+1<temp.size()&&temp[k + 1] == 1)
				{
					return false;
				}
			}
			else if (k == temp.size() - 1)
			{
				if (k-1>=0&&temp[k - 1] == 1)
				{
					return false;
				}
			}
			else
			{
				if (temp[k - 1] == 1 || temp[k + 1] == 1)
					return false;
			}
			return true;

		}
	}

	bool canPlaceFlowers(vector<int>& flowerbed, int n)
	{
		if (n == 0)
		{
			return true;
		}
		for (int i = 0; i < flowerbed.size(); i++)
		{
			if (canPlace(flowerbed,i))
			{
				n--;
				if (n <= 0)
				{
					return true;
				}
				flowerbed[i] = 1;
			}
		}
		return false;

	}
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值