Find All Good Indices
Find All Good Indices
You are given a 0-indexed integer array nums of size and a positive integer .
We call an index in the range good if the following conditions are satisfied:
- The elements that are just before the index are in non-increasing order.
- The elements that are just after the index are in non-decreasing order.
Return an array of all good indices sorted in increasing order.
Example 1:
Input: nums = [2,1,1,1,3,4,1], k = 2 Output: [2,3] Explanation: There are two good indices in the array: - Index 2. The subarray [2,1] is in non-increasing order, and the subarray [1,3] is in non-decreasing order. - Index 3. The subarray [1,1] is in non-increasing order, and the subarray [3,4] is in non-decreasing order. Note that the index 4 is not good because [4,1] is not non-decreasing.
Example 2:
Input: nums = [2,1,1,2], k = 2 Output: [] Explanation: There are no good indices in this array.
Constraints:
解题思路
做这题的时候很容易想到对于每一个,可以直接每次暴力枚举区间和看看是否满足要求,但这样做会超时,然后又发现这相当于询问一个区间是否满足非递增或非递减,因此比赛的时候直接用线段树去实现了。
AC代码如下:
1 const int N = 1e5 + 10; 2 3 class Solution { 4 public: 5 struct Node { 6 int l, r; 7 bool f1, f2; 8 }tr[N * 4]; 9 vector<int> a; 10 11 void build(int u, int l, int r) { 12 if (l == r) { 13 tr[u] = {l, r, true, true}; 14 } 15 else { 16 int mid = l + r >> 1; 17 build(u << 1, l, mid); 18 build(u << 1 | 1, mid + 1, r); 19 tr[u] = {l, r, tr[u << 1].f1 && tr[u << 1 | 1].f1 && a[mid] >= a[mid + 1], tr[u << 1].f2 && tr[u << 1 | 1].f2 && a[mid] <= a[mid + 1]}; 20 } 21 } 22 23 Node query(int u, int l, int r) { 24 if (tr[u].l >= l && tr[u].r <= r) return tr[u]; 25 int mid = tr[u].l + tr[u].r >> 1; 26 if (r <= mid) { 27 return query(u << 1, l, r); 28 } 29 else if (l >= mid + 1) { 30 return query(u << 1 | 1, l, r); 31 } 32 else { 33 Node t1 = query(u << 1, l, r); 34 Node t2 = query(u << 1 | 1, l, r); 35 Node ret; 36 ret.f1 = t1.f1 && t2.f1 && a[mid] >= a[mid + 1]; 37 ret.f2 = t1.f2 && t2.f2 && a[mid] <= a[mid + 1]; 38 return ret; 39 } 40 } 41 42 vector<int> goodIndices(vector<int>& nums, int k) { 43 int n = nums.size(); 44 a = nums; 45 build(1, 0, n - 1); 46 vector<int> ans; 47 for (int i = k; i < n - k; i++) { 48 if (query(1, i - k, i - 1).f1 && query(1, i + 1, i + k).f2) ans.push_back(i); 49 } 50 return ans; 51 } 52 };
下面给出正解,反正我是想不到的。
先预处理一个,表示以为右端点,且单调递减的序列的最大长度。再预处理一个表示以为左端点,且单调递增的序列的最大长度。
对于,如果有,那么;否则如果有,那么。
同理对于,如果有,那么;否则如果有,那么。
因此当我们想要判断第个位置是否满足要求,就可以看是否同时满足和。
AC代码如下:
1 class Solution { 2 public: 3 vector<int> goodIndices(vector<int>& nums, int k) { 4 int n = nums.size(); 5 vector<int> f(n), g(n); 6 for (int i = 0; i < n; i++) { 7 f[i] = 1; 8 if (i && nums[i] <= nums[i - 1]) f[i] = f[i - 1] + 1; 9 } 10 for (int i = n - 1; i >= 0; i--) { 11 g[i] = 1; 12 if (i + 1 < n && nums[i] <= nums[i + 1]) g[i] = g[i + 1] + 1; 13 } 14 15 vector<int> ans; 16 for (int i = k; i < n - k; i++) { 17 if (f[i - 1] >= k && g[i + 1] >= k) ans.push_back(i); 18 } 19 return ans; 20 } 21 };
参考资料
力扣第312场周赛:https://www.bilibili.com/video/BV13Y4y1K7eU
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16728119.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效