传送门 思路 题目是很标准的“找到最大或最小”,也就是说假设正解为ans,(-∞,ans)范围内都无法满足题设条件,而[ans,+∞)都能满足要求,且ans是满足要求的值中最小的那个,这样ans就是一个“合法与非法”的分割点。对于形如这样的题设,就可以对答案序列进行二分来在一个较优的复杂度内枚举到答案。 就本体内容具体地看,天数显然就是我们二分的目标。枚举的左边界是0,右边界是bloomDay中最大值,这是显然地。 每次获取一个mid,然后去检查这个天数mid能否满足要求。如果可以的话,说明mid落在了[ans,+∞)范围内,令r=mid,继续; 如果不可以满足要求,那么说明mid落在了(-∞,ans) 范围内,令l=mid+1,缩小范围继续查找。 值得一提的是,与传统的二分不同,我们在缩小右边界时并非是r=mid-1,这是因为答案区间[ans,+∞)是左闭右开的,是可能存在r==ans的,如果这时还去-1,就会导致答案错误。 代码 ```cpp class Solution { public: int minDays(vector& bloomDay, int m, int k) { const int n = bloomDay.size(); if (m * k > n) return -1; vector flag(n); int l = 0, r = *max_element(bloomDay.begin(), bloomDay.end()); …
传送门 T1:截断句子 思路 签到题,用python会比cpp简单很多。直接按空格split然后分片就行。 代码 ```python class Solution(object): def truncateSentence(self, s, k): """ :type s: str :type k: int :rtype: str """ ss = s.split(" ") if k == len(ss): return s ans = " ".join(ss[:k]) return ans ``` 赛后感觉写的太冗长了,可以精简成一句: ```python class Solution(object): def truncateSentence(self, …
传送门 t1 圆形赛道上经过次数最多的扇区 有一个圆形区域,被分成n块扇区,给出一系列起点与终点,问跑到最后经过次数最多的扇区是哪些。 赛时居然没过这题... 当时写了一个模拟,因为没处理好边界问题,死活过不去。赛后下来看了发现确实想复杂了。 我们要发现一个事实,因为赛道是圆形的,所以除了结尾的那一圈“不完整”的赛程,之前若干圈赛程都是没有意义的,因为每个扇区都同时累加了经过次数,“同时”在本题中是没有讨论意义的。所以我们的答案只用关注最后那不完整的赛程经过了哪些扇区。 值得注意的是,起点不一定是第一块扇区,所以要处理越界问题。同时,观察样例不难发现答案是有序的,所以还要对最终答案数组做一个排序。 ```cpp class Solution { public: vector mostVisited(int n, vector& rounds) { vectorans; int l = rounds[0]; int r = rounds[rounds.size()-1]; while(l != r) { if(l == n+1) { l %= n; continue; } ans.push_back(l++); } ans.push_back(r); …
传送门 t1 存在连续三个奇数的数组 签到题,直接O(n²)遍历就能过。 ```cpp class Solution { public: bool threeConsecutiveOdds(vector& arr) { const int n = arr.size(); if(n < 3) return false; for(int i = 2; i < n; i++) { int cnt = 0; for(int j = i-2; j <= i; j++) …