【LetMeFly】 2100. Um bom dia para roubar um banco
Agora parece que o assunto
2100. 适合野炊的日子
mudou .
Link da pergunta Leetcode: https://leetcode.cn/problems/find-good-days-to-rob-the-bank/
Você e um grupo de ladrões vão roubar um banco. Você recebe uma matriz de números inteiros cujo índice começa em 0security
, onde security[i]
é i
o número de guardas de plantão no dia. Os dias 0
estão contados desde o início. Também fornece um número inteiro time
.
Se i
o dia satisfizer todas as condições a seguir, consideramos que é um dia adequado para roubar um banco:
i
Há pelo menos um dia antes e depois do primeiro diatime
.i
O número de guardas em dias consecutivos antes do primeiro diatime
não aumenta.- O número de guardas não diminui em dias
i
consecutivos após o primeiro dia.time
Mais formalmente, um dia i
é um dia adequado para roubar um banco se e somente se: security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time]
.
Por favor, retorne um array contendo todos os dias adequados para assalto a banco (o subscrito começa em 0 ). Os dias retornados podem estar em qualquer ordem.
Exemplo 1:
Entrada: segurança = [5,3,3,3,5,6,2], tempo = 2 Saída: [2,3] Explicação: No dia 2, temos segurança[0] >= segurança[1] >= segurança[2] <= segurança[3] <= segurança[4] . No dia 3, temos security[1] >= security[2] >= security[3] <= security[4] <= security[5] . Nenhum outro dia se enquadra neste critério, portanto os dias 2 e 3 são bons dias para assaltos a bancos.
Exemplo 2:
Entrada: segurança = [1,1,1,1,1], tempo = 0 Saída: [0,1,2,3,4] Explicação: Como o tempo é igual a 0, todo dia é um dia adequado para roubar um banco. Então retorne todos os dias.
Exemplo 3:
Entrada: segurança = [1,2,3,4,5,6], tempo = 2 Saída: [] Explicação: Não há número não crescente de guardas nos primeiros 2 dias de qualquer dia. Portanto, não há dias adequados para assalto a banco e uma matriz vazia é retornada.
dica:
1 <= security.length <= 105
0 <= security[i], time <= 105
Ideias
Método 1: discussão de classificação
<pequena complexidade de tempo O ( n ) O (n)O ( n ) , complexidade do espaço O (1), dificuldade ※※** </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)
tempo = 0 tempo = 0hora _ _=No caso de 0, atenção especial deve ser dada à inserção de links e imagens.
Portanto usamos duas variáveis lian X u X ia D ays lianXuXiaDaysl ian X u X ia D a ys (representando dias não crescentes) ecould A s Up 4 B egin couldAsUp4Beginpoderia começar 4 ( O dia a partir de agora em que a não - decrescente pode começar )
Ou seja, em dias consecutivos de lian X u X ia lianXuXiaDaysl ian X u X ia Dias após dias não crescentes, se lian X ul ian X u X ia Dias _ _≥ti im e , então contanto quetempocontínuohojeO tempo não diminui a cada dia, hoje é o “dia do roubo”.
Então estamos em lian X u X ia D ays ≥ tempo lianXuXiaDays\geq timel ian X u X ia Dias _ _≥quando o tempo , você pode mudarpoderia A s Up 4 Begin couldAsUp4Beginpoderia ser 4 começar Marque isso como hoje . _ _ _ _ _
Se o tempo depoisdias e acima não estão diminuindo, então o registropoderia As Up 4 Begin couldAsUp4Begin neste momentopoderia ser um " dia de roubo " . _ _ _ _ _
Portanto, no percurso para trás, se ainda estiver no estado não decrescente, pode-se julgar se poderia As Up 4 Begin couldAsUp4Beginpoderia u l d A s Up 4 B e g in , se houver ( ≠ − 1 \neq -1=− 1 ) Apenas julgue a distância de hojepoderia A s Up 4 Begin couldAsUp4Beginco u l d A s Up 4 B e g em se≥ tempo \geq tempo≥t im e dias se≥ tempo \geq tempo≥tempo , o emprego poderia A s Up 4 B egin couldAsUp4Beginpoderia l d A s Up 4 B e g no tempocontínuo _ _o tempo em que os dias não são decrescentes, entãopoderia A s Up 4 Begin couldAsUp4Beginpoderia u ld A s Up 4 Começar é um dia de assalto .
Para uma descrição mais detalhada, consulte os comentários
Código AC
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 dois
Complexidade de tempo O ( n ) O (n)O ( n ) , complexidade espacial O (n), dificuldade※
Este método é mais fácil de implementar que o método anterior, mas a complexidade do espaço é maior que o método anterior.
Podemos usar O (n) O (n)A complexidade de tempo de O ( n ) é encontrar o "número de dias consecutivos não crescentes antes" e "o número de dias consecutivos não decrescentes depois" para cada dia.
xia [i] xia[i]x ia [ i ] display nºiiHá dias sem aumento antes do dia,shang [i] shang[i]s hang g [ i ] displayNo.Quantos dias antes do meu dia não são decrescentes
Método específico: percorre o array de frente para trás, if今天≤昨天
, then
xia[i] = xia[i - 1] + 1
; caso contrário,
xia[i] = 0
. Valor inicial
xia[0] = 0
Percorre o array de trás para frente, se
今天≤昨天
, então
shang[i] = shang[i + 1] + 1
; caso contrário,
shang[i] = 0
. valor inicial
shang[security.size() - 1] = 0
Então percorremos cada dia, se um dia satisfizer xia [ i ] ≥ tempo xia[i]\geq timexia [ eu ] _≥t im e和shang [ i ] ≥ tempo shang[i] \geq timeShang [ eu ] _ _≥hora , hoje é dia de roubo .
Código AC
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;
}
};
O artigo é publicado simultaneamente na CSDN. Não é fácil ser original. Anexe o link para o artigo original após reimpressão com o consentimento do autor ~
Tisfy: https://letmefly.blog.csdn.net/article/details/133324938