No hay mucho que decir: los primeros resultados llaman la atención
consejo: para volúmenes de datos más grandes u otros entornos más exigentes, considere dividir y conquistar
Resultados de la prueba
El consumo de
memoria que consume mucho tiempo :
configuración de computadora mínima (sin vmvare, se le ocurre la idea 4M)
demanda
Cómo extraer los 100 números más grandes en el nivel de datos 1E.
Idea:
Use una lista individualmente vinculada ordenada personalizada para filtrar (aquí en orden ascendente)
- Para valores más pequeños que el valor más a la izquierda, descartar directamente sin ningún procesamiento
- Para valores mayores que el valor más a la derecha (máximo), la lista vinculada se desplaza hacia la derecha (es decir, se elimina el más a la izquierda y se agrega el más a la derecha)
- Para valores mayores que el valor más a la izquierda y menores que el valor máximo, el subíndice se desplaza hacia la derecha hasta que se encuentra un valor mayor que él,
- Para solo mayor que el valor más a la izquierda, cambie el valor directamente al valor más a la izquierda
- Para el valor medio (más grande que el valor más a la izquierda y más pequeño que el valor más a la derecha), asignamos el nodo más a la izquierda al valor e insertamos la
idea central (se ha obtenido la posición 2) +
para un volumen de datos de orden de magnitud mayor, Se puede adoptar la idea de divide y vencerás, por lo que teóricamente la idea puede manejar órdenes ilimitadas de datos.
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;
}
}
}