[LeetCode/笔试]605. Can Place Flowers + 2020vivo提前批笔试第一题

[LeetCode]605. Can Place Flowers

  • 一、vivo真题
  • 二、Leetcode题目
  • 三、解题思路
    • 3.1 直接解法
    • 3.2 优化解法

上周末,实验室师兄参加Vivo的提前批笔试。一共三道题,都是LeetCode的原题,只是vivo在题干中添加了自己公司大段文案,加上了一个外包装,看上去题目非常的长,实际上没有增加题目难度,和原题一模一样。

根据vivo提前批笔试题目顺序,依次带来这三道LeetCode题目。

一、vivo真题


以上图片就是vivo第一题,来自LeetCode 605. Can Place Flowers,一道easy题,比较简单。

二、Leetcode题目

Problem Description:
Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die.

Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule.

Example 1:
Input: flowerbed = [1,0,0,0,1], n = 1
Output: True

Example 2:
Input: flowerbed = [1,0,0,0,1], n = 2
Output: False

Note:
1.The input array won’t violate no-adjacent-flowers rule.
2.The input array size is in the range of [1, 20000].
3.n is a non-negative integer which won’t exceed the input array size.

三、解题思路

3.1 直接解法

直接求解的思路很简单,遍历所有元素,找出值为0的元素(意味着这是一个空位置)。对于元素值为0元素,检查它的两个相邻位置是否也是0。如果满足以上条件这样,我们可以在当前位置种植一朵花flowerbed[index] = 1;,而不违反禁止相邻种花的规则。对于第一个元素,不需要检查它的前一个元素;对于最后一个元素,不需要检查下一个元素。
((当前元素=0) && (第一个元素||前一个元素=0) && (最后一个元素||后一个元素=0))
((flowerbed[index] == 0) && ((index == 0) || (flowerbed[index-1] == 0)) && ((index == flowerbed.length-1) || (flowerbed[index+1] == 0)))
找到一个位置,计数+1,若大于等于初始给定的n,则返回true。所有元素遍历完成后,仍未大于等于初始给定的n,则返回false。

注意:
一定要注意((index == 0) || (flowerbed[index-1] == 0))((index == flowerbed.length-1) || (flowerbed[index+1] == 0)),要采用 || 的短路操作,使(index == 0)(index == flowerbed.length-1)先进行判断,否则会造成数组下标越界。

对于vivo原题,只需要遍历计数,直接返回计数总数即可。

算法时间复杂度为O(n),空间复杂度为O(1)

//Time complexity : (n).
//Space complexity : O(1).
class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        int index = 0;
        int cnt = 0;
        while(index < flowerbed.length){
            //((当前元素=0) && (第一个元素||前一个元素=0) && (最后一个元素||后一个元素=0))
            if((flowerbed[index] == 0) && ((index == 0) || (flowerbed[index-1] == 0)) && ((index == flowerbed.length-1) || (flowerbed[index+1] == 0))){//关键:||短路操作
                flowerbed[index] = 1;//需要这一步
                cnt++;
            }
            if(cnt >= n){
                return true;
            }
            index++;
        }
        return false;
    }
}

以上代码的提交结果:
[LeetCode/笔试]605. Can Place Flowers + 2020vivo提前批笔试第一题_第1张图片

3.2 优化解法

优化解法的关键在于:
1.The input array won’t violate no-adjacent-flowers rule.
由于输入的数组也满足禁止相邻种花的规则,所以元素值=1的元素前后位置的值一定=0,即010。

伪代码:
‘0’或‘1’:当前遍历元素
X:下一个遍历元素

if(当前元素值=1)
	根据The input array won't violate no-adjacent-flowers rule.条件,其前后元素一定=0,即010X,所以索引可以直接+2遍历元素X
else // 当前元素值=0
	(隐含条件:如果当前元素的前一个元素值=1,根据上面描述索引直接+2,无法遍历到当前元素,假设不成立,所以当前元素的前一个元素一定=0if(下一个元素值=0)
		000X,可以种植,计数+1,索引直接+2遍历下一个元素X
	else // 下一个元素值=1
		因为下一个元素值=1,根据The input array won't violate no-adjacent-flowers rule.条件,则下下一个元素值=0,即0010X,索引直接+3遍历元素X。其实,对于下一个元素1来说,也就是索引+2

根据分析伪代码的所有情况,当前遍历元素和下一个遍历元素X的前一个元素值一定=0(这点是非常重要的!),所以根据以上优化算法的思想,我们不再需要判断当前遍历元素的上一个元素值。(如果这里不明白的,可以停下来多思考一下,或者在纸上画一下就比较清楚了)

边界条件:防止数组下标越界
①由于不需要考虑当前遍历元素的前一个元素,所以自然不用考虑第一个元素。
②考虑最后一个元素,要先进行索引值判断(index == flowerbed.length-1),也是采用 || 短路操作来实现 ((index == flowerbed.length-1) || (flowerbed[index+1] == 0))

算法时间复杂度为O(n),空间复杂度为O(1)
此优化方法不需要判断当前遍历元素的前一个元素值,且每次遍历索引+2或+3,加速了数组的遍历。

//关键:The input array won't violate no-adjacent-flowers rule.
//Time complexity : 少于O(n/2).
//Space complexity : O(1).
class Solution {
    public boolean canPlaceFlowers(int[] flowerbed, int n) {
        int index = 0;
        int cnt = 0;
        while(index < flowerbed.length){
            if(flowerbed[index] == 1){
                index += 2;
            }else{//flowerbed[index] == 0,
                if((index == flowerbed.length-1) || (flowerbed[index+1] == 0)){//关键:||短路操作
                    //flowerbed[index] = 1;//不需要这一步
                    cnt++;
                    index += 2;
                }else if(flowerbed[index+1] == 1){
                	index += 3;
                }
            }
            if(cnt >= n){
                return true;
            }
        }
        return false;
    }
}

以上代码的提交结果:
[LeetCode/笔试]605. Can Place Flowers + 2020vivo提前批笔试第一题_第2张图片

你可能感兴趣的:([LeetCode/笔试]605. Can Place Flowers + 2020vivo提前批笔试第一题)