[Entrevista LeetCode-Classic 150 perguntas-dia 11]

Índice

128.A sequência contínua mais longa

 228. Intervalo de resumo

 56. Mesclar intervalos

 57.Inserir intervalo

 452. Detonar o balão com o mínimo de flechas


 

128.A sequência contínua mais longa

Significado da pergunta:

Dado um array não classificado de inteiros  nums , encontre o comprimento da sequência mais longa de números consecutivos (os elementos da sequência não precisam ser consecutivos no array original).

Projete e implemente  O(n) um algoritmo com complexidade de tempo para resolver este problema.

【Amostra de entrada】

números = [100,4,200,1,3,2]

【Amostra de saída】

4

Explicação: A sequência contínua mais longa de números é [1,2,3,4]

Ideias para resolução de problemas: tabela hash

1. Use set, que não contém elementos repetidos, portanto, primeiro armazenamos os elementos em nums no conjunto para obter um efeito de desduplicação.

2. Percorra o conjunto. Quando o dígito anterior num-1 de um número num não estiver na matriz, significa que pode ser o primeiro dígito da sequência contínua. Continue percorrendo para ver se o próximo dígito num+1 está em o conjunto.Se o comprimento estatístico existe até não ser encontrado.

class Solution {
    public int longestConsecutive(int[] nums) {
        int count = 0;
        Set<Integer> numSet = new HashSet<>();
        for(int num : nums){
            numSet.add(num);
        }
        int tempCount;
        for(int num : numSet){
            if(!numSet.contains(num-1)){
                tempCount = 1;//第一个数
                while(numSet.contains(++num)){
                    ++tempCount;//继续查找
                }
                count = Math.max(count,tempCount);
            }
        }
        return count;
    }
}

Tempo: bater 84,51%

Memória: Bata 89,54%

 228. Intervalo de resumo

Significado da pergunta:

Dada uma    matriz  classificada  de  números inteiros sem elementos duplicados  .nums

Retorna   uma lista dos  menores intervalos ordenados que cobrem exatamente todos os  números  do array . Ou seja, nums cada elemento de é exatamente coberto por um determinado intervalo de intervalo, e não existe nenhum  nums número  que pertença a um determinado intervalo, mas não o faça x .

Cada intervalo de intervalo na lista  [a,b] deve ser gerado no seguinte formato:

  • "a->b" ,se a != b
  • "a" ,se a == b

【Amostra de entrada】

números = [0,1,2,4,5,7]

【Amostra de saída】

["0->2","4->5","7"]

Ideias para resolução de problemas: enumeração

class Solution {
    public List<String> summaryRanges(int[] nums) {
        List<String> list = new ArrayList<>();
        if(nums.length == 0){
            return list;
        }
        if(nums.length == 1){
            list.add(String.valueOf(nums[0]));
            return list;
        }
        int i=0;
        while(i < nums.length){
            int low = i;
            ++i;
            while(i<nums.length && nums[i] == nums[i-1]+1){
                ++i;
            }
            int high = i-1;
            String str;
            if(low == high){
                str = String.valueOf(nums[low]);
            }else{
                str = nums[low]+"->"+nums[high];
            }
            list.add(str);
        }
        return list;

    }
}

Tempo: Derrotado 51,34%

Memória: derrotada por 16,07%

 56. Mesclar intervalos

Significado da pergunta:

Use uma matriz  intervals para representar um conjunto de vários intervalos, onde um único intervalo é  intervals[i] = [starti, endi] . Mescle todos os intervalos sobrepostos e retorne  uma matriz de intervalos não sobrepostos que cubra exatamente todos os intervalos na entrada  .

【Amostra de entrada】

intervalos = [[1,3],[2,6],[8,10],[15,18]]

【Amostra de saída】

[[1,6],[8,10],[15,18]]

Ideias para resolução de problemas: classificação + julgamento de enumeração

1. Primeiro, classifique a matriz bidimensional fornecida em ordem crescente de acordo com o intervalo esquerdo.

2. Julgamento de enumeração, as variáveis ​​leftBound e rightBound registram os limites esquerdo e direito atuais; enumeração, se o limite esquerdo do próximo intervalo for menor que o limite direito atual, prova que os dois intervalos podem ser mesclados e o limite direito é modificado (não modificar cegamente, para mudar para um valor maior, como (1,6), (2,4), a modificação direta se tornará (1,4), então você precisa julgar); se o limite esquerdo do O próximo intervalo é maior que rightBound, isso prova que os intervalos atuais não podem ser mesclados e são adicionados ao array.

class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> res = new ArrayList<>();    
        //按照左边界排序
        Arrays.sort(intervals, (x,y)-> Integer.compare(x[0],y[0]));
        //initial start 是最小左边界
        int leftBound = intervals[0][0];
        int rightBound = intervals[0][1];//右边界
        for(int i=1;i< intervals.length;++i){
            //如果左边界大于上一个有边界
            if(intervals[i][0] > rightBound){
                //加入区间,更新start,加入的是上一个区间
                res.add(new int[]{leftBound,rightBound});
                leftBound = intervals[i][0];
                rightBound = intervals[i][1];
            }else{
                //更新右边界
                rightBound = Math.max(rightBound, intervals[i][1]);
            }
        }
        res.add(new int[]{leftBound,rightBound});
        return res.toArray(new int[res.size()][]);
    }
}

Tempo: bater 80,99%

Memória: Bata 92,51%

 57.Inserir intervalo

Significado da pergunta:

Fornece uma lista  não sobreposta de intervalos  classificados pelos pontos inicial e final dos intervalos.

Ao inserir um novo intervalo em uma lista, você precisa ter certeza de que os intervalos na lista ainda estão ordenados e não se sobrepõem (mesclando os intervalos, se necessário).

【Amostra de entrada】

intervalos = [[1,3],[6,9]], novoIntervalo = [2,5]

【Amostra de saída】

[[1,5],[6,9]]

Ideias para resolução de problemas: semelhante à pergunta anterior, mas esta questão não requer classificação

Enumere o intervalo original e considere quatro situações:

1. Quando o limite direito do i-ésimo elemento no intervalo original for menor que o limite esquerdo do intervalo inserido, insira o i-ésimo elemento diretamente no intervalo original;

2. Quando o limite esquerdo do i-ésimo elemento no intervalo original for maior que o limite direito do intervalo inserido, o novo intervalo é inserido e marcado como inserido. Quando esta situação for determinada posteriormente, os elementos do intervalo original são adicionados diretamente;

3. O terceiro caso, exceto 1 e 2, significa que o i-ésimo elemento do intervalo original se sobrepõe ao intervalo inserido, e os intervalos esquerdo e direito são atualizados julgando os valores máximo e mínimo dos dois intervalos .

4. Neste último caso, após o intervalo original ter sido percorrido e o novo intervalo não ter sido inserido, ele é inserido diretamente no final.

class Solution {
    public int[][] insert(int[][] intervals, int[] newInterval) {
        boolean isInsert = false;//是否已经插入
        List<int[]> list = new ArrayList<>();
        int leftBounds = newInterval[0];//新区间的左边界
        int rightBounds = newInterval[1];//新区间的右边界
        for(int i=0;i<intervals.length;++i){
            if(intervals[i][0] > rightBounds){
                if(!isInsert){
                    list.add(new int[]{leftBounds,rightBounds});
                    isInsert = true;
                }
                list.add(new int[]{intervals[i][0],intervals[i][1]});
            }else if(intervals[i][1] < leftBounds){
                //在插入区间的左侧
                list.add(new int[]{intervals[i][0],intervals[i][1]});
            }else{
                //有交集,要合并区间
                leftBounds = Math.min(leftBounds,intervals[i][0]);
                rightBounds = Math.max(rightBounds,intervals[i][1]);
            }
        }
        //如果遍历完还没有插入,添加到最后
        if(!isInsert){
            list.add(new int[]{leftBounds,rightBounds});
        }
        return list.toArray(new int[list.size()][]);
    }
}

Tempo: bater 97,50%

Memória: derrotada por 67,95%

 452. Detonar o balão com o mínimo de flechas

Significado da pergunta:

Existem alguns balões esféricos presos a uma parede representada pelo plano XY. Os balões na parede são registrados em uma matriz de números inteiros  points , que points[i] = [xstart, xend] representam  balões com diâmetros horizontais entre xstart e  . xendVocê não sabe a coordenada y exata do balão.

Um arco e flecha podem ser disparados perfeitamente verticalmente a partir de diferentes pontos ao longo do eixo x   . Atire uma flecha nas coordenadas  x . Se as coordenadas inicial e final do diâmetro de um balão forem  xstart, xend, e forem satisfeitas   xstart ≤ x ≤ xend, o balão será  detonado  . Não há limite para o número de flechas que podem ser disparadas   . Depois que o arco e a flecha são disparados, ele pode avançar indefinidamente.

Você recebe um array  points que retorna o número mínimo  de flechas  que devem ser disparadas para explodir todos os balões  .

dica:

  • 1 <= points.length <= 105
  • points[i].length == 2
  • -231 <= xstart < xend <= 231 - 1

【Amostra de entrada】

pontos = [[10,16],[2,8],[1,6],[7,12]]

【Amostra de saída】

2

Ideias para resolução de problemas: Semelhante a 56. Intervalo de mesclagem, a diferença é que ao atualizar o limite direito agora, você precisa pressionar o menor.

class Solution {
    public int findMinArrowShots(int[][] points) {  
        //按照左边界排序
        Arrays.sort(points, (x,y)-> Integer.compare(x[0],y[0]));
        int result = 1;
        for(int i=1;i< points.length;++i){
            //如果左边界大于上一个有边界
            if(points[i][0] > points[i-1][1]){
                //加入区间,更新start,加入的是上一个区间
                ++result;
            }else{
                //更新右边界
                points[i][1] = Math.min(points[i-1][1], points[i][1]);
            }
        }
        // int result = res.size;
        return result;
    }
}

Tempo: Derrotado 18,88%

Memória: derrotada por 82,02%

Acho que você gosta

Origin blog.csdn.net/qq_37998848/article/details/132403923
Recomendado
Clasificación