豆包 LeetCode 2251. 花期内花的数目 public int[] fullBloomFlowers(int[][] flowers, int[] people)
2026/5/10 9:03:02 网站建设 项目流程

LeetCode 2251 解题思路 + 最优代码

这道题是经典的差分 + 排序 + 二分问题,非常高频,最优解法时间复杂度O(n log n + m log n)

题目理解

  • flowers[i] = [start, end]:花从startend每天都开放
  • people[i]:人到达的时间
  • 要求返回:每个人到达时,正开放的花有多少朵

核心思路(最优解法)

  1. 把花期拆分成两个事件
    • 花开:start位置 +1
    • 花谢:end + 1位置 -1(因为 end 当天还开着)
  2. 对所有时间点排序
  3. 对 people 数组排序(保留原始下标)
  4. 用双指针/前缀和 + 二分快速统计每个人到达时的花数

完整 Java 代码

importjava.util.*;classSolution{publicint[]fullBloomFlowers(int[][]flowers,int[]people){intn=flowers.length;intm=people.length;// 1. 收集花开、花谢时间int[]starts=newint[n];int[]ends=newint[n];for(inti=0;i<n;i++){starts[i]=flowers[i][0];ends[i]=flowers[i][1];}// 2. 排序Arrays.sort(starts);Arrays.sort(ends);// 3. 对每个人:二分查找 <= time 的花开数量 - 小于 time 的花谢数量int[]res=newint[m];for(inti=0;i<m;i++){inttime=people[i];// 花开 <= time:有多少朵intbloom=upperBound(starts,time);// 花谢 < time:有多少朵intfall=lowerBound(ends,time);res[i]=bloom-fall;}returnres;}// 找 <= target 的最后一个位置 +1(总数)privateintupperBound(int[]arr,inttarget){intl=0,r=arr.length;while(l<r){intmid=l+(r-l)/2;if(arr[mid]<=target){l=mid+1;}else{r=mid;}}returnl;}// 找 < target 的第一个位置(总数)privateintlowerBound(int[]arr,inttarget){intl=0,r=arr.length;while(l<r){intmid=l+(r-l)/2;if(arr[mid]<target){l=mid+1;}else{r=mid;}}returnl;}}

公式解释(最关键)

对某个人到达时间time
开放花数 = 已经开放的花数量 - 已经凋谢的花数量

  • 已经开放 = 花开时间 ≤ time
  • 已经凋谢 = 花谢时间 < time(end 当天仍开放)

复杂度

  • 排序:O(n log n)
  • 每个人二分:O(m log n)
  • 总体:O(n log n + m log n)
  • 空间:O(n)

这是最优解法,能轻松通过题目最大数据量。


总结

  1. 拆分花期为开始数组结束数组并排序
  2. 对每个人到达时间用二分计算开花数 - 凋谢数
  3. 时间复杂度最优、代码简洁、面试高频标准答案

需要我给你讲差分法版本(更直观的区间计数思路)吗?

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询