leetcode刷題筆記605

Comic2213發表於2021-01-01

寫在前邊

  • 今天的每日一題是個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;

	}
};

相關文章