【LetMeFly】2100. Un buen día para robar un banco
Ahora parece que
2100. 适合野炊的日子
se ha .
Enlace de pregunta de Leetcode: https://leetcode.cn/problems/find-good-days-to-rob-the-bank/
Tú y un grupo de ladrones vais a robar un banco. Se le proporciona una serie de números enteros cuyo índice comienza en 0security
, donde security[i]
es i
el número de guardias de servicio ese día. Los días 0
están contados desde el principio. También te da un número entero time
.
Si i
el día cumple todas las condiciones siguientes, lo llamamos un día adecuado para robar un banco:
i
Hay al menos un día antes y después del primer díatime
.i
El número de guardias en días consecutivos antes del primer díatime
no aumenta.- El número de guardias no disminuye en días
i
consecutivos después del primer día.time
Más formalmente, el día i
es un día adecuado para robar un banco si y sólo si: security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time]
.
Devuelva una matriz que contenga todos los días adecuados para el robo a un banco (el subíndice comienza en 0 ). Los días devueltos pueden estar en cualquier orden.
Ejemplo 1:
Entrada: seguridad = [5,3,3,3,5,6,2], tiempo = 2 Salida: [2,3] Explicación: El día 2, tenemos seguridad[0] >= seguridad[1] >= seguridad[2] <= seguridad[3] <= seguridad[4] . El día 3, tenemos seguridad[1] >= seguridad[2] >= seguridad[3] <= seguridad[4] <= seguridad[5] . Ningún otro día cumple con este criterio, por lo que los días 2 y 3 son buenos días para robos a bancos.
Ejemplo 2:
Entrada: seguridad = [1,1,1,1,1], tiempo = 0 Salida: [0,1,2,3,4] Explicación: Debido a que el tiempo es igual a 0, cada día es un día adecuado para robar un banco Así que regresa todos los días.
Ejemplo 3:
Entrada: seguridad = [1,2,3,4,5,6], tiempo = 2 Salida: [] Explicación: No hay un número no creciente de guardias en los primeros 2 días de cualquier día. Por lo tanto, no hay días adecuados para el robo de un banco y se devuelve una matriz vacía.
pista:
1 <= security.length <= 105
0 <= security[i], time <= 105
Ideas
Método 1: discusión sobre clasificación
<complejidad de tiempo pequeño O ( n ) O (n)O ( n ) , complejidad espacial O (1), dificultad ※※** </smtps://leetcode-cn.com/problems/find-good-days-to-rob-the-bank/solution/letmefly-fen -lei-tao-lun-on-o1-by-letmef-1jgw/](https://img-blog.csdnimg.cn/img_convert/ca4a6ec46181f3756420620dbe776075.jpeg)
tiempo = 0 tiempo = 0tiempo _ _=En el caso de 0, se debe prestar especial atención a la inserción de enlaces e imágenes.
Por lo tanto usamos dos variables lian X u X ia D ays lianXuXiaDaysl ian X u X ia D a ys (que representa días no crecientes) ymight A s Up 4 B egin mightAsUp4Beginco u l d A s Up 4 Be g in (El día a partir de ahora en el que puede comenzar la no disminución)
Es decir, en lianXuXiaDays consecutivosl ian X u X ia Días después de días no crecientes, si lian X ul ian X u X ia D a ys≥ti im e , entonces siempre y cuandotiempocontinuohoyEl tiempo no disminuye día a día, hoy es el "día del robo" .
Entonces estamos en lian X u X ia D ays ≥ tiempo lianXuXiaDays\geq tiempol ian X u X ia D a ys≥cuando el tiempo , puedes cambiar might A s Up 4 B egin mightAsUp4Beginco u l d A s Up 4 Comenzar Márquelo como hoy . _
Si el tiempo despuésLos días de tiempo y superiores no están disminuyendo, entonces el registropodría A s Up 4 Begin mightAsUp4Begin en este momentoco u l d A s Up 4 Be g in es un "día de robo " .
Por lo tanto, en el recorrido hacia atrás, si todavía está en el estado no decreciente, se puede juzgar si podría existir A s Up 4 B egin mightAsUp4Beginco u l d A s U p 4 B e g in , si hay (≠ − 1 \neq -1=− 1 ) Simplemente juzgue la distancia de hoy.might A s Up 4 B egin mightAsUp4Beginco u l d A s U p 4 B e g en si≥ tiempo \geq tiempo≥t im e días si≥ tiempo \geq tiempo≥t im e, El empleopodría A s Up 4 B egin mightAsUp4Beginco u l d A s Up 4 Be g en el tiempocontinuo _tiempo los días no son decrecientes, por lo quepodría A s Up 4 Begin podría AsUp4Beginco u l d A s Up 4 Be g in es un día de robo .
Para una descripción más detallada, consulte los comentarios.
código de CA
C++
class Solution {
public:
vector<int> goodDaysToRobBank(vector<int>& security, int time) {
if (!time) {
// time = 0,每天都是“打劫日”
vector<int> ans(security.size()); // 答案共有security.size()天
for (int i = 0; i < security.size(); i++) {
ans[i] = i; // 第i个答案是第i天
}
return ans;
}
vector<int> ans;
int lianXuXiaDays = 0; // 连续↓或→的天数
int couldAsUp4Begin = -1; // 最早可以认为是开始连续上升的那一天 | 如果couldAsUp4Begin=a≠-1,说明第a天之前至少有time天的非递增
for (int i = 1; i < security.size(); i++) {
// 从第二天开始遍历
if (security[i] < security[i - 1]) {
// ↓
lianXuXiaDays++; // 连续非递增天数++
if (lianXuXiaDays >= time) {
// 如果连续非递增天数≥time,那么今天之前就有≥time的非递减
couldAsUp4Begin = i; // 从今天开始可以非递减了
}
else {
// 还没有连续非递增time天
couldAsUp4Begin = -1;
}
}
else if (security[i] == security[i - 1]) {
// 今天和昨天相等,也就是说既符合非递增又符合非递减
lianXuXiaDays++; // 符合非递增,连续非递增天数++
if (couldAsUp4Begin != -1) {
// 前面有≥time的非递减,并且从那天起没有递增的一天 | Lable1
if (i - couldAsUp4Begin >= time) {
// 如果今天距离那天≥time,那天就是抢劫日
ans.push_back(couldAsUp4Begin); // 先把抢劫日添加到答案中去
if (security[couldAsUp4Begin + 1] <= security[couldAsUp4Begin]) {
// 如果抢劫日的下一天仍然是非递增,那么下一天之前肯定有至少time天的非递增
couldAsUp4Begin++; // 下一天也可以作为开始非递减的一天
}
else {
// 否则
couldAsUp4Begin = -1; // 下一天>这个抢劫日,说明下一天必不满足“前面有至少time天的非递增”
}
}
}
else {
// couldAsUp4Begin = -1
if (lianXuXiaDays >= time) {
// 连续非递增天数≥time
couldAsUp4Begin = i; // 从今天起可以开始非递减了
}
}
}
else {
// 今 > 昨
lianXuXiaDays = 0; // 连续非递减天数中断
if (couldAsUp4Begin != -1) {
// 这个同理于上面的“Lable1”处
if (i - couldAsUp4Begin >= time) {
ans.push_back(couldAsUp4Begin);
if (security[couldAsUp4Begin + 1] <= securmai ty[coul AsUp4Begin]) {
couldA Up4B gectin++;
}
已完成 else {
}
couldA }
}
Up4Begin = -1;
}
}
}
}
return ans; // 返回答案即可
}
};
Método dos
Complejidad del tiempo O ( n ) O (n)O ( n ) , complejidad espacial O (n), dificultad ※
Este método es más fácil de implementar que el método anterior, pero la complejidad del espacio es mayor que el método anterior.
Podemos usar O ( n ) O(n)La complejidad temporal de O ( n ) es encontrar el "número de días consecutivos no crecientes antes" y "el número de días consecutivos no decrecientes después" para cada día.
x i a [ i ] xia[i] x ia [ i ] pantalla nºiiHay días que no aumentan antes del día i ,shang [ i ] shang [i]s han g [ i ] pantalla nºii¿Cuántos días antes del día i son no decrecientes?
Método específico: atravesar la matriz de adelante hacia atrás, si今天≤昨天
, entonces
xia[i] = xia[i - 1] + 1
; en caso contrario
xia[i] = 0
,. Valor inicial
xia[0] = 0
Recorre la matriz de atrás hacia adelante, si
今天≤昨天
, entonces
shang[i] = shang[i + 1] + 1
; en caso contrario
shang[i] = 0
,. valor inicial
shang[security.size() - 1] = 0
Luego recorremos cada día, si un día satisface xia [ i ] ≥ time xia[i]\geq timexia [ yo ] _≥t im e和shang [ i ] ≥ tiempo shang[i] \geq tiemposhang [ yo ] _ _≥Tiempo , este día es el día del robo.
código de CA
C++
class Solution {
public:
vector<int> goodDaysToRobBank(vector<int>& security, int time) {
vector<int> xia(security.size());
vector<int> shang(security.size());
xia[0] = 0, shang[shang.size() - 1] = 0;
for (int i = 1; i < security.size(); i++) {
xia[i] = security[i] > security[i - 1] ? 0 : xia[i - 1] + 1;
}
for (int i = security.size() - 2; i >= 0; i--) {
shang[i] = security[i] > security[i + 1] ? 0 : shang[i + 1] + 1;
}
vector<int> ans;
for (int i = 0; i < security.size(); i++) {
if (xia[i] >= time && shang[i] >= time)
ans.push_back(i);
}
return ans;
}
};
El artículo se publica simultáneamente en CSDN. No es fácil ser original. Adjunte el enlace al artículo original después de la reimpresión con el consentimiento del autor ~
Tisfy: https://letmefly.blog.csdn.net/article/details/133324938