2100. 适合打劫银行的日子题解
题目来源:2100. 适合打劫银行的日子
2022.03.06 每日一题
每日一题专栏地址:LeetCode 每日一题题解更新中❤️💕
今天的题目思路很容易理解,找到security
数组中满足security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time]
的索引
这题目越来越刑了,怎么办
首先第一个想法就是直接暴力求解
数据范围
1 <= security.length <= 105
0 <= security[i], time <= 105
有点多,尝试了一下,不错,最后TLE
了,那就想方法优化一下
使用 n 来表示 数组的长度
首先第一个优化的思路就是,首先要满足security
数组的长度要大于time
的2倍,
因此我们可以直接将范围缩小到 [ t i m e , n − t i m e ) [time,n-time) [time,n−time)
接下来我们就来优化如何判断前 time 个元素非递增,后 time 个元素非递减
我们可以使用前缀和的思想来判断当前索引i
是否满足前 time 个元素非递增,后 time 个元素非递减
class Solution {
public:
vector<int> goodDaysToRobBank(vector<int> &security, int time) {
int n = security.size();
if (n <= 2 * time)
return {};
// 创建一个统计数组,来统计 security 数组是否是递增/递减的
// 1 代表是递减的,-1 代表是递增的, 0 代表两者相等
vector<int> temp(n), left(n + 1), right(n + 1);
// 遍历数组 寻求是否是非递增或者是否是非递减
for (int i = 1; i < n; i++) {
if (security[i] == security[i - 1])
continue;
temp[i] = security[i] > security[i - 1] ? 1 : -1;
}
// 找到递增与递减的位置
for (int i = 1; i <= n; i++) left[i] = left[i - 1] + (temp[i - 1] == 1 ? 1 : 0);
for (int i = 1; i <= n; i++) right[i] = right[i - 1] + (temp[i - 1] == -1 ? 1 : 0);
vector<int> res;
// 寻找满足条件的结果
for (int i = time; i < n - time; i++)
if ((left[i + 1] == left[i + 1 - time]) && (right[i + 1 + time] == right[i + 1]))
res.push_back(i);
return res;
}
};
class Solution {
public ArrayList<Integer> goodDaysToRobBank(int[] security, int time) {
int n = security.length;
ArrayList<Integer> res = new ArrayList<>();
if (n <= 2 * time) return res;
// 创建一个统计数组,来统计 security 数组是否是递增/递减的
// 1 代表是递减的,-1 代表是递增的, 0 代表两者相等
int[] temp = new int[n], left = new int[n + 1], right = new int[n + 1];
// 遍历数组 寻求是否是非递增或者是否是非递减
for (int i = 1; i < n; i++) {
if (security[i] == security[i - 1]) continue;
temp[i] = security[i] > security[i - 1] ? 1 : -1;
}
// 找到递增与递减的位置
for (int i = 1; i <= n; i++) left[i] = left[i - 1] + (temp[i - 1] == 1 ? 1 : 0);
for (int i = 1; i <= n; i++) right[i] = right[i - 1] + (temp[i - 1] == -1 ? 1 : 0);
// 寻找满足条件的结果
for (int i = time; i < n - time; i++)
if ((left[i + 1] == left[i + 1 - time]) && (right[i + 1 + time] == right[i + 1])) res.add(i);
return res;
}
};
下面是TLE
的代码
class Solution {
public:
vector<int> goodDaysToRobBank(vector<int> &security, int time) {
int len = security.size();
if (len <= 2 * time)
return {};
vector<int> res;
for (int i = time; i < len - time; i++) {
if (check(security, time, i, true) && check(security, time, i, false))
res.push_back(i);
}
return res;
}
bool check(vector<int> &security, int time, int index, bool isIncrement) {
if (time == 0)
return true;
if (isIncrement) {
for (int i = index - time; i < index; i++) {
if (security[i] < security[i + 1])
return false;
}
return true;
}
for (int i = index; i < index + time; i++) {
if (security[i] > security[i + 1])
return false;
}
return true;
}
};
class Solution {
public ArrayList<Integer> goodDaysToRobBank(int[] security, int time) {
int len = security.length;
ArrayList<Integer> res = new ArrayList<>();
if (len <= 2 * time) return res;
for (int i = time; i < len - time; i++) {
if (check(security, time, i, true) && check(security, time, i, false)) res.add(i);
}
return res;
}
boolean check(int[] security, int time, int index, boolean isIncrement) {
if (time == 0) return true;
if (isIncrement) {
for (int i = index - time; i < index; i++)
if (security[i] < security[i + 1]) return false;
return true;
}
for (int i = index; i < index + time; i++)
if (security[i] > security[i + 1]) return false;
return true;
}
};