LeetCode 2100. Um bom dia para roubar um banco

【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 dia time .
  • i O número de guardas em dias consecutivos antes do primeiro dia time 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 tempot im e dias se≥ tempo \geq tempotempo , 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 eshang [ 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

Acho que você gosta

Origin blog.csdn.net/Tisfy/article/details/133324938
Recomendado
Clasificación