Caderno de coleta de lixo de cem milhões de níveis de 78 ms para alcançar a classificação de bilhões de níveis (parte 2)

Não há muito a dizer: os primeiros resultados chamam a atenção

Dica: Para maiores volumes de dados ou outros ambientes mais exigentes, considere dividir e conquistar

Resultado dos testes

O consumo de
Insira a descrição da imagem aqui
memória demorado :
configuração de computador mínima (sem vmvare, surge com a ideia 4M)
Insira a descrição da imagem aqui

exigem

Como extrair os 100 maiores números no nível de dados 1E.
Ideia:
Use uma lista personalizada e unicamente vinculada para filtrar (aqui em ordem crescente)

  1. Para valores menores do que o valor mais à esquerda, descarte diretamente sem qualquer processamento
  2. Para valores maiores do que o valor mais à direita (máximo), a lista vinculada é deslocada para a direita (ou seja, a mais à esquerda é excluída e a mais à direita é adicionada)
  3. Para valores maiores que o valor mais à esquerda e menores que o valor máximo, o subscrito é deslocado para a direita até que um valor maior que ele seja encontrado,
  4. Para valores maiores que apenas à esquerda, altere o valor diretamente para o valor mais à esquerda
  5. Para o valor do meio (maior que o valor mais à esquerda e menor que o valor mais à direita), atribuímos o nó mais à esquerda ao valor e inserimos o nó do meio (a posição 2 foi obtida)
    idea +
    para um volume de dados de ordem de magnitude maior, nós A ideia de dividir para conquistar pode ser adotada, então a ideia pode teoricamente lidar com pedidos ilimitados de dados
package practice;

import java.util.*;

public class Main {
    
    
    class ListNode {
    
    
        int val;
        ListNode next;
        public ListNode() {
    
    
        }

        public ListNode(int val) {
    
    
            this.val = val;
        }
    }
    public ListNode createNode(int val){
    
    
        return new ListNode(val);
    }
    public static void main(String[] args) {
    
    
        Main main = new Main();
        int ti=0;
        //赋予1E个随机数字,用于排序
        int[] arr=new int[10000*10000];
        Random random=new Random();
        for (int i = 0; i < arr.length; i++) {
    
    
            arr[i]=random.nextInt();
        }
        //开始计时
        long start = System.currentTimeMillis();
        //抽取数组前100位并排序,用于初始化链表
        int[] ints = Arrays.copyOfRange(arr, 0, 100);
        Arrays.sort(ints);
        ListNode root=main.createNode(0);
        root.next=main.createNode(Integer.MIN_VALUE);
        ListNode curr=root.next;
        //记录最后一个
        ListNode last=curr;
        //初始化长度100的链表
        for (int i = 0; i < ints.length; i++) {
    
    
            curr.next=main.createNode(ints[i]);
            last=curr;
            curr=curr.next;
        }

        //筛除最大100个
        for (int i = 0; i < arr.length; i++) {
    
    
            curr=root.next;
            //比最左大才判断,否则直接舍弃
            if (arr[i]>curr.val) {
    
    
                //首先跟最右比较,比最右大
                if (arr[i] >= last.val) {
    
    
                    //是最大,删除最左,添加最右
                    root.next = root.next.next;
                    last.next = main.createNode(arr[i]);
                    last = last.next;
                } else {
    
    
                    //比最左边大,下标右移,直至右边比其大
                    while (curr.next != null && arr[i] > curr.next.val) {
    
    
                        curr = curr.next;
                    }
                    //右移完成
                    //处于最左边,最左边直接复制
                    if (curr.val==root.next.val) {
    
    
                        curr.val=arr[i];
                    }
                    //处于中间
                    else {
    
    
                        //增加新中间节点,废物利用,减少新对象的创建
                        ListNode node=root.next;
                        node.val=arr[i];
                        //删除最左节点
                        root.next = root.next.next;
                        //串联新增节点
                        node.next=curr.next;
                        curr.next=node;
                    }
                }
            }
        }
        //计时结束
        System.out.println("总计用时");
        System.out.println(System.currentTimeMillis()-start);
        //遍历,校验结果
        curr=root.next;
        while (curr!=null)
        {
    
    
            System.out.println(curr.val);
            curr=curr.next;
        }
    }
}



Acho que você gosta

Origin blog.csdn.net/weixin_43158695/article/details/113199734
Recomendado
Clasificación