刷爆力扣之种花问题

简介: 刷爆力扣之种花问题

一 🏠 题目描述

605. 种花问题


]假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。


给你一个整数数组 flowerbed 表示花坛,由若干 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 <= flowerbed.length <=2 * 104flowerbed[i] 为 01flowerbed 中不存在相邻的两朵花
0 <= n <= flowerbed.length


二 🏠破题思路

2.1 🚀 关键信息

解决问题第一步,当然先提取题目字面上的关键信息 😎😎😎


花不能种植在相邻的地块上,即


① 当 0 在数组两端时,只需要两个零即可可以栽上一棵花


② 当 0 不在数组两端时,需连续出现三个 0 才可以栽上一棵花 🌸🌸🌸



提取完题目中的关键信息后,直接进入第二阶段,思路整理 😃😃😃



2.2 🚀 思路整理

防御式编程法


防御性编程作用在于,引入额外条件以忽略临界条件下与正常状态的不同,以该题为例 🌹🌹🌹


数组两端各增加一个 0,任意位置处只要连续出现三个 0 就可以栽上一棵花。因为至少三个 0 才可以种花(不在两边的情况下),因此在数组两端各加一个 0 ,这样处理可以不需要考虑边界条件


当临界值为1 时,加上 0 对结果无影响;当临界值为 0 时,因处于临界状态时,两个 0 正好等效于中间状态下的三个 0 (即可种一颗树),故该题可使用防御式编程法可规避掉复杂临界状态的分支判断 🌺🌺🌺



整理完解题思路后,直接进入第三阶段,代码实现 😃😃😃



三 🏠 代码详解

3.1 🚀 代码实现

按照我们刚才的破题思路,直接代码走起来 👇👇👇👇


bool canPlaceFlowers(vector<int>& flowerbed, int n) {
     int len =1, ans =0; //认为左边界提供 10for (auto &i : flowerbed) {
if (i) { //为 1 , 此处已种花
             ans += (len -1) / 2; //len 个 0 可种 (len -1) / 2 朵花
             len =0;
         } else { //为 0 , 此处为空地
++len;
         } 
     }
     ans += len / 2; // 处理 0 尾,认为右边界提供一个 0     return ans >= n; //返回比较结果
 }


3.2 🚀 细节解析

看完 👀👀👀 全注释版的代码实现后,相信看官大大对整体逻辑已经是大写的 OK 了 😃😃😃


那么我们挖掘上述实现的晦涩细节 😖😖😖 进行解析,直接开干,走起来 👇👇👇👇


ans += (len -1) / 2; //len 个 0 可种 (len -1) / 2 朵花

使用数学归纳 . . . ,4 个 0 可种 1 朵,5 个 0 可种 2 朵,6 个 0 可种 2 朵,7 个 0 可种 3 朵,. . .


易知当 len 为奇数且每隔两个数可种花的数量加一,即推导出 len 个 0 可种 (len - 1) / 2 朵花 🐌🐌🐌



ans += len / 2; // 处理 0 尾,认为右边界提供一个 0

使用数学归纳 . . . ,2 个 0 可种 1 朵,3 个 0 可种 2 朵,4 个 0 可种 2 朵,5 个 0 可种 2 朵,. . .


易知对于以 0 结尾的情况,当 len 为偶数且每隔两个数可种花的数量加一,即推导出 len 个 0 可种 len / 2 朵花 🐳🐳🐳



四 🏠 心路历程

为方便各位看官大大了解博主真实刷题过程,我把当时状态纯纯真实还原,记录在心路历程这一小节,不感兴趣的小伙伴可以直接跳过哈


博主在第一阶段提取 🚀 关键信息没有问题,在第二阶段 🚀 思路整理未联想到使用防御式编程法


代码实现使用了分类讨论法,分成最左端,中间,最右端三种情况 😶😶😶 ,代码如下 👇👇👇👇


bool canPlaceFlowers(vector<int>& flowerbed, int n) {
    int len = flowerbed.size();
if (len ==1) {
if (flowerbed[0] ==0) return n > 1 ? false : true;
else return n > 0 ? false : true;
    } 
    int count =0;
for (int i =0; i < len; ++i) {
if (flowerbed[i] ==0) {
if (i ==0) { //索引位置处于最左端
if (flowerbed[i +1] ==0) flowerbed[i] =1, ++count;
            } elseif (i == len -1){ //索引位置处于最右端
if (flowerbed[i -1] ==0) flowerbed[i] =1, ++count;
            } else {  //索引处于中间
if (flowerbed[i +1] ==0 && flowerbed[i -1] ==0) flowerbed[i] =1,++count;
            }
        }
    }
    return n > count ? false : true;
}


目录
打赏
0
0
0
0
3
分享
相关文章
智能化运维的崛起:机器学习在IT管理中的实践与挑战
本文深入探讨了智能化运维领域,特别是机器学习技术在IT管理中的应用。文章首先介绍了智能化运维的概念及其重要性,随后详细阐述了机器学习在故障预测、自动化响应和系统优化中的作用。同时,文章也指出了实施智能化运维时可能遇到的技术挑战和数据治理问题,并提出了相应的解决策略。最后,通过具体案例分析,展示了机器学习技术如何在实际运维中提高系统稳定性和效率。
数据仓库的分层架构与演进
分层架构很容易在各种书籍和文档中去理解,但是把建模方法和分层架构放在一起就会出现很多困惑了。接下来,我会从数据研发与建模的角度,演进一下分层架构的设计原因与层次的意义。
16458 3
数据仓库的分层架构与演进
【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
236 0
【Qt 常用枚举】Qt TextFormat 枚举的深入解析
【Qt 常用枚举】Qt TextFormat 枚举的深入解析
328 0
对YTKNetwork的官方demo的一些补漏
对YTKNetwork的官方demo的一些补漏
236 1
龙芯2K驱动开发——使用中断触发读取GPIO电平值上传给读取进程
龙芯2K驱动开发——使用中断触发读取GPIO电平值上传给读取进程
604 0
龙芯2K驱动开发——使用中断触发读取GPIO电平值上传给读取进程
Harbor用户机制、镜像同步和与Kubernetes的集成实践
Habor是由VMWare公司开源的容器镜像仓库。事实上,Habor是在Docker Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用,这些新的企业级特性包括:管理用户界面,基于角色的访问控制 ,AD/LDAP集成以及审计日志等。
3346 0

热门文章

最新文章

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问