【刷题日记】2100. 适合打劫银行的日子

简介: 本次刷题日记的第 2 篇,力扣题为:2100. 适合打劫银行的日子 ,中等

【刷题日记】2100. 适合打劫银行的日子

本次刷题日记的第 2 篇,力扣题为:2100. 适合打劫银行的日子中等

一、题目描述:

image.png

示例如下:

image.png

image.png

二、思路分析:

1、这道题考察了什么思想?你的思路是什么?

看了这题的描述和示例,我们应该得到了如下几个信息

  • 如果 time 等于 0 ,那么每一天都可以打劫银行,那么结果就是给出数组的所有下标
  • 如果 time 比整个数组都大,结果一定是一个空数组,哪一天都不适合打劫
  • 根据我们选择打劫的时间,需要满足这个条件: security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time]
    根据条件,我们知道,无论选择哪一天打劫,需要满足,当天前需要有 time 天,且当天后也要有 time 天, 同时,前后的 time 天还要满足数据的要求,我们数组长度需要满足这个条件才有的玩:2 * time + 1 小于等于数组的长度

[ 5, 3, 3, 3, 5, 6, 2 ] ,time = 2 为例

当我们选中某一个是否可以打劫的时候,当天的前 time 天 和当天的后 time 天在数组上对应的数据是向当天的数据,逐渐变小的

image.png

那这样做起来就不难理解的,我们是否感觉和上一篇分享的刷题有点类似,我们是否也可以看成是转换成特殊的子数组的方式来处理,例如这样

image.png

咱们只需要找到满足前 time 天和后 time 天对应的区间,然后校验区间是否满足题目中的要求:打劫当天的前 time 天,数字递减(可以相等),打劫当天的后 time 天,数字递增(可以相等)

2、尝试编码

那么,根据上述的图示和逻辑,那么咱们不难写出类似于这样的代码

image.png

看样子感觉也没啥问题,那么咱们提交吧

提交后发现,给我们报了一个 超出时间限制


查看具体错误情况的时候,我们可以看到跑通了 128 个用例,但是对于一些数据量比较大的时候,上述的这种编码方式就不满足本题的要求了

image.png

那么,一定是有优化的空间,肯定是哪里处理的低效了

3、思考和探索

来我们一起来探索一下,同样还是 以 [ 5, 3, 3, 3, 5, 6, 2 ] ,time = 2 为例

选择第一个区间的时候,打劫日是在下标为 2 的位置上,数字是 3, 那么需要循环的的去判断 打劫日 和 前 2 个数字,是否递减,同理,循环判断打劫日和后 2 个数字是否是递增,如果是,那么我们就得到一个打劫日

image.png

那么继续往下推进

image.png

当推进到下一个区间的时候,如果我们还是使用上述的方式,使用循环的方式来校验是否递增或者递减的话,那就会出现上面编码的结果**,对于数据量大的时候,时间超出限制**

实际上,对于上一个区间,我们已经明确知道打劫日的前后数据递增或者递减关系,那么区间往后走的时候,我们指定的新的打劫日

只需要和上一个打劫日比较,当前打劫日上的数据,是否小于上一个打劫日上的数据且再判断当前区间的最右边的值,是否大于上一个打劫日区间的最右边值 即可

做一个这样的优化,那么对于多个打劫日挨在一起的区间时,我们就能大大降低循环的此时,大大减少时间复杂度

源码如下:

func goodDaysToRobBank(security []int, time int) []int {
  if time >= len(security) || 2*time+1 > len(security) {
    return []int{}
  }
  if time == 0 {
    res := []int{}
    for i, _ := range security {
      res = append(res, i)
    }
    return res
  }
  length := len(security)
  res := []int{}
  flag := true
  preloc := 0  // 上一次打劫日的下标
  preLastRight := 0  // 上一次打劫日所在区间最右边的数字下标
  for i := time; i <= length-1-time; i++ {
    if flag { // 判断需要使用 循环进行确认是否是打劫日
      if isOk(security, i, time) {
        res = append(res, i)
        flag = false
        preloc = i
        preLastRight = i + time
        continue
      }
    } else {
      if security[i] <= security[preloc] && security[i+time] >= security[preLastRight] { // 可以直接和上一个打劫日进行比较即可
        flag = false
        res = append(res, i)
        preloc = i
        preLastRight = i + time
      } else {
        flag = true
      }
    }
  }
  return res
}
// 判断是否是打劫日
func isOk(security []int, loc int, time int) bool {
  for i := loc - time; i < loc; i++ {
    if security[i] < security[i+1] {
      return false
    }
  }
  for i := loc + time; i > loc; i-- {
    if security[i] < security[i-1] {
      return false
    }
  }
  return true
}

通过上述编码,和注释,我们就不难看出,本次的编码比上面尝试的编码高效了许多,减少了许多无用的循环

当然这只是其中一种解法,感兴趣的朋友可以看看更好的解法,例如官方的这种,直接引入 2 个数组,一个记录当前下标左边的递减情况,一个记录右边的递增情况,如下图这样

image.png

image.png

四、总结:

本题的解法,空间复杂度是 O(n),n 是对应数组的长度,官方的解法时间复杂为 O(n),n 是对应数组的长度,感兴趣的可以一起刷起来

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~


相关文章
|
9月前
|
存储 人工智能 Serverless
大学生们注意了,你的拜年姿势准备好了吗?
来尝试一种全新的“数字人”拜年方式吧。上传个人照片,即可一键创建数字人分身,还可以搭配春节服饰、背景、拜年模板,生成专属的数字人拜年视频,简单无门槛,有心更有新。
154 7
|
9月前
|
运维 算法 Java
程序员去银行:建信金科24届秋招记录
【2月更文挑战第16天】本文介绍2024届秋招中,建信金融科技有限责任公司的软件开发工程师岗位2场面试的基本情况、提问问题,以及体检情况等~
135 4
程序员去银行:建信金科24届秋招记录
LeetCode-2100 适合打劫银行的日子
LeetCode-2100 适合打劫银行的日子
|
9月前
|
网络协议 算法 Java
从外卖员到程序员,自学3年终于转行成功,三面“拿下”拼多多
老家农村,家里好不容易把我送到大城市读书,大学非985,211,但在我们老家,能出一个本科大学生也是非常不容易的。因为农村信息的相对闭塞,我对大学专业一无所知,加上分数并非前茅,最后被调剂一个我并不喜欢的专业,这里就不透露自己是什么学校了,只能说毕业之后为了能多赚点,选择了送外卖,这一送就送了将近3年的时间。
|
9月前
|
NoSQL 算法 关系型数据库
入职字节跳动那一天,我哭了(蘑菇街被裁,奋战7个月拿下offer)
先说一下自己的个人情况,18届应届生,通过校招进入到了蘑菇街,然后一待就待了差不多2年多的时间,可惜的是今年4月份受疫情影响遇到了大裁员,而我也是其中一员。好在早有预感,提前做了准备,之前一直想去字节跳动,年前就已经在做准备了,这场持久战拉得很长,也最终以7个月的时间取得胜利。在踏入字节跳动,办理入职手续的那一天,作为一个男子汉,确实是落泪了。特分享一波我的真实经历,共勉。
|
9月前
|
机器学习/深度学习
2021牛客暑期多校训练营1(补题)
2021牛客暑期多校训练营1(补题)
49 0
|
9月前
PAT甲级真题1061:约会
PAT甲级真题1061:约会
48 0
|
双11
双十一里的公益:老乡寄来一封手写信,感谢每一位热心助农的你 原创 小益 阿里巴巴公益 2022-11-09 20:30 发表于浙江
各位亲,分享一件小事: 前阵子,小益收到了一封手写信,来自山西平顺县龙溪镇佛堂岭村的老乡。
496 0
双十一里的公益:老乡寄来一封手写信,感谢每一位热心助农的你 原创 小益 阿里巴巴公益 2022-11-09 20:30 发表于浙江
|
算法
牛客网———公务员面试
牛客网———公务员面试
211 0
|
SQL 安全 前端开发
来来来开小灶了,年后求职和跳槽的看过来,悄悄的看悄悄的收藏
面试官,您好我叫(XXX),今天来公司面试 JAVA开发工程师,之前在(XXX 公司)任职,从事这一行已经有(几)个年头了。这几年开发,主要接触的项目包括(你做过的项目!)等。在开发过程中,也用过好些框架,比如∶ springboot、springcloud、springmvc、spring、Mybatis等技术框架。熟练掌握框架之间的整合技术。有时候因为项目需求或是为了开发的高效性,自己我会研究一些技术,使用一些常用的主流 Java技术,例如∶(吹!用没用过不重要,主要是就是英文的!)。前端的技术也研究过一些。如(原生的、框架啊都往上整!)
219 0
来来来开小灶了,年后求职和跳槽的看过来,悄悄的看悄悄的收藏