Comparación de montón + objeto de estructura de datos versión java

 En el primer día de 2022, tigre ah tigre ah, ¡les deseo a todos un próspero año del tigre! ! ! Ya está aquí el primer blog del año.

contenido

1. Hacer preguntas

2. Comparación de elementos

2.1 Comparación de elementos

2.2 Comparación de objetos

3. Comparación de Objetos

3.1 Anulando el igual de la clase base

3.2 Comparación basada en la clase de interfaz Comparble

3.3 Comparación basada en comparador

3.4 Comparación de tres métodos

6. El problema del montón que sobró de la última lección

6.1 Problema TopK

6.2 Preguntas de la entrevista


1. Hacer preguntas

En el blog anterior, premiamos la cola de prioridad. La cola de prioridad tiene un requisito al insertar elementos: el elemento insertado no puede ser nulo o los elementos deben compararse . Para simplificar, solo insertamos el tipo Entero , la prioridad Puede ¿Insertas objetos de tipo personalizado en la cola?
Vamos a ver
①Cuando el elemento insertado es nulo: (No importa cuándo inserte nulo, se informará una excepción de puntero nulo)

2. Comparación de elementos 

2.1 Comparación de tipos básicos

En Java , los objetos de tipos primitivos se pueden comparar directamente en tamaño.
public class TestCompare { 
public static void main(String[] args) { 
//①整型数据的比较
int a = 10; int b = 20; 
System.out.println(a > b);
 System.out.println(a < b); 
System.out.println(a == b); 
//②字符型数据的比较
char c1 = 'A'; 
char c2 = 'B'; 
System.out.println(c1 > c2); 
System.out.println(c1 < c2); 
System.out.println(c1 == c2); 
//布尔类型数据的比较
boolean b1 = true; 
boolean b2 = false; 
System.out.println(b1 == b2); 
System.out.println(b1 != b2); } }

2.2 Comparación de objetos

class Card { 
public int rank; 
// 数值 public String suit; 
// 花色 public Card(int rank, String suit) {
 this.rank = rank;
 this.suit = suit; 
} 
}
public class TestPriorityQueue { 
public static void main(String[] args) {
Card c1 = new Card(1, "♠"); 
Card c2 = new Card(2, "♠"); 
Card c3 = c1; 
System.out.println(c1 > c2); 
// 编译报错 
System.out.println(c1 == c2); 
// 编译成功 ----> 打印false,因为c1和c2指向的是不同对象
System.out.println(c1 < c2); // 编译报错 
System.out.println(c1 == c3); // 编译成功 ----> 打印true,因为c1和c3指向的是同一个对象 
}
 }

3. Comparación de objetos

En algunos casos, es necesario comparar el contenido del objeto. Por ejemplo, cuando se inserta un objeto en la cola de prioridad, el almacenamiento dinámico debe ajustarse de acuerdo con el contenido del objeto. ¿Cómo solucionarlo?

3.1 Anulando el igual de la clase base

Nota: cuando un tipo personalizado quiera comparar si los dos son iguales y tienen el mismo contenido, asegúrese de anular su método de igualdad.

Modificar el código a:

class Card{
    public int rank;
    public String suit;
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    @Override
    public String toString() {
        return "Card{" +
                "rank=" + rank +
                ", suit='" + suit + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
//如果this引用和o引用 引用的是同一个对象
        if (this == o) return true;
//getClass()这里比较的是是不是同一个类型,不是的话返回false;当然此处可以用instanceof来判断
//if (o == null || !(o instanceof Card))可以用此语句来代替
        if (o == null || getClass() != o.getClass()) return false;
        Card card = (Card) o;
//数字一样并且花色一样,那么逻辑上就是一样的
        return rank == card.rank && Objects.equals(suit, card.suit);
    }
    @Override
    public int hashCode() {
        return Objects.hash(rank, suit);
    }
}
public class TestDemo {
    public static void main(String[] args) {
        Card card1 = new Card(1, "♥");
        Card card2 = new Card(1, "♥");
        System.out.println(card1.equals(card2));

    }

Nota: La rutina general para anular los iguales es como se muestra arriba
1. Si apunta al mismo objeto, devuelve verdadero
2. Si la entrada es nula , devuelve falso
3. Si el tipo de objeto entrante no es Tarjeta , devuelve falso
4. Complete la comparación de acuerdo con el objetivo de realización de la clase, por ejemplo, siempre que el palo y el valor sean iguales, se considera que es la misma carta
5. Tenga en cuenta que la comparación de otros tipos de referencia también requiere iguales , como la comparación de traje aquí
Aunque se puede comparar el método de anular la clase base equal , el defecto es: equal solo se puede comparar de acuerdo con la igualdad, y no se puede comparar de acuerdo con mayor que o menor que . v

3.2 Comparación basada en la clase de interfaz Comparble

  Para tener la capacidad de comparar, implemente la interfaz Comparable aquí y compare las partes específicas que necesita (el valor predeterminado aquí es la comparación de montones pequeños)

el código se muestra a continuación:

import java.util.PriorityQueue;
//要具备比较的能力
class Card implements Comparable<Card>{
    public int rank;
    public String suit;
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    @Override
    public String toString() {
        return "Card{" +
                "rank=" + rank +
                ", suit='" + suit + '\'' +
                '}';
    }
    @Override
    public int compareTo(Card o) {
        //自己定义比较的内容
        return o.rank-this.rank;
    }
}
public class TestDemo {
    public static void main(String[] args) {
        //默认底层为小根堆,每存入一个元素均会进行比较
        PriorityQueue<Card>priorityQueue=new PriorityQueue<>();
        priorityQueue.offer(new Card(2,"♥"));//存取第一个元素时实际上是直接放到底层的queue数组的0下标
        priorityQueue.offer(new Card(1,"♥"));
        System.out.println(priorityQueue);

    }

 3.3 Comparación basada en comparador

 el código se muestra a continuación:

import java.util.Comparator;
import java.util.PriorityQueue;
//要具备比较的能力
class Card{
    public int rank;
    public String suit;
    public Card(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    @Override
    public String toString() {
        return "Card{" +
                "rank=" + rank +
                ", suit='" + suit + '\'' +
                '}';
    }
}
        class RankCompartor implements Comparator<Card>{
            @Override
            public int compare(Card o1, Card o2) {
                return o1.rank-o2.rank;
            }
        }
public class TestDemo {
    public static void main(String[] args) {
        //默认底层为小根堆,每存入一个元素均会进行比较
    Card card1=new Card(1,"♥");
    Card card2=new Card(2,"♥");
    RankCompartor rankCompartor=new RankCompartor();
    int ret=rankCompartor.compare(card1,card2);
        System.out.println(ret);
    }

También puede utilizar los siguientes dos métodos:

Método 1: clase interna anónima

 PriorityQueue<Card> priorityQueue = new PriorityQueue<>(new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o1.rank-o2.rank;
            }
        });

Método ②: expresión lambda


        PriorityQueue<Card> priorityQueue = new PriorityQueue<>((x,y)->{return y.rank-x.rank;});

 3.4 Comparación de tres métodos

 compareTo está más inclinado a las clases

6. El problema del montón que sobró de la última lección

6.1 Problema TopK

Idea ①: Ordene el conjunto y genere los 10 elementos más grandes. (manera habitual de pensar)

Idea 2: use el montón que acaba de aprender antes

Idea ③: a. Primero cree los primeros 3 elementos como un montón raíz pequeño
              b. Debido a que el montón actual es un montón raíz pequeño, entonces el elemento superior del montón debe ser el más pequeño de los primeros k elementos. Si hay un elemento más grande que el elemento superior del montón, reemplaza el elemento superior del montón y este elemento puede ser uno de los superiores. Por el contrario, si se trata de un montón raíz grande, no es necesariamente
              c. Después de sacar el elemento superior del montón, se ajustará de nuevo a un montón raíz pequeño.


el código se muestra a continuación:

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;

//求数组中前k个最小的元素,建大堆
public class TopK {
    public static int[] topK(int []array,int k){
        //创建一个大小为k的大根堆
        PriorityQueue<Integer> maxHeap=new PriorityQueue<>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        //遍历数组当中的元素,将前k个元素放入队列中
        for (int i = 0; i < array.length ; i++) {
            if(maxHeap.size()<k){
                maxHeap.offer(array[i]);
            }else{
                //从k+1个元素开始,每个元素和堆顶元素进行比较
                int top=maxHeap.peek();
                if(top>array[i]){
                    //现将大的弹出
                    maxHeap.poll();
                    //再将小的存入
                    maxHeap.offer(array[i]);
                }
            }
        }
        int[]tmp=new int[k];
        for (int i = 0; i <k ; i++) {
            tmp[i]=maxHeap.poll();

        }
        return tmp;
    }

    public static void main(String[] args) {
        int []array={18,21,8,10,34,12};
        int []tmp=topK(array,3);
        System.out.println(Arrays.toString(tmp));
    }
}

Problema de clasificación de montón:

Ideas para resolver problemas: (la condición final es que el final sea 0)

① Ajuste el montón a un gran montón raíz

②El subíndice 0 se puede intercambiar con el último elemento sin clasificar 

③fin--

④ Ajuste el montón hacia abajo de nuevo al montón de raíz grande

el código se muestra a continuación: 

  public void heapSort() {
        int end = this.usedSize - 1;
        while (end > 0) {
            int tmp = elem[0];
            elem[0] = elem[end];
            elem[end] = tmp;
            shiftDown(0, end);
            end--;
        }
    }

6.2 Preguntas de la entrevista

373. Buscar y los pares de números K más pequeños: LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/find-k-pairs-with-smallest-sums/

tema:

Dadas dos matrices de enteros nums1 y nums2 en orden ascendente, y un entero k.

Defina un par de valores (u,v) donde el primer elemento proviene de nums1 y el segundo elemento proviene de nums2.

Encuentra los k pares con la suma más pequeña (u1,v1), (u2,v2) ... (uk,vk) .

Idea para resolver problemas: (en realidad también es un problema topK, la diferencia es que se cambia a la suma más pequeña de los primeros k)

? ? ? la pregunta es esa? ? ? Cómo poner un conjunto de pares

PriorityQueue<Lista<Entero>>

el código se muestra a continuación:

  public static List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {

        PriorityQueue<List<Integer>> maxHeap = new PriorityQueue<>(k, new Comparator<List<Integer>>() {
            @Override
            public int compare(List<Integer> o1, List<Integer> o2) {
//获取List中的某个元素需要使用get()方法
                return (o2.get(0)+o2.get(1))-(o1.get(0)+o1.get(1));
            }
        });
//        for (int i = 0; i < Math.min(nums1.length,k); i++) {
//            for (int j = 0; j < Math.min(nums2.length,k); j++) {
        for (int i = 0; i < nums1.length; i++) {
            for (int j = 0; j < nums2.length; j++) {
//还没放满的情况下
                if(maxHeap.size() < k) {
                    List<Integer> tmpList = new ArrayList<>();
                    tmpList.add(nums1[i]);
                    tmpList.add(nums2[j]);
                    maxHeap.offer(tmpList);
                }else {
//获取顶元素的值
                    int top = maxHeap.peek().get(0) + maxHeap.peek().get(1);
                    if(top > nums1[i]+nums2[j]) {
                        //记住  要弹出的
                        maxHeap.poll();
                        List<Integer> tmpList = new ArrayList<>();
                        tmpList.add(nums1[i]);
                        tmpList.add(nums2[j]);
                        maxHeap.offer(tmpList);
                    }
                }
            }
        }
        List<List<Integer>> ret = new ArrayList<>();
        for (int i = 0; i < k && !maxHeap.isEmpty(); i++) {
            ret.add(maxHeap.poll());
        }
        return ret;
    }

    public static void main(String[] args) {
        int[] nums1 = {1,7,11};
        int[] nums2 = {2,4,6};
        List<List<Integer>> ret = kSmallestPairs(nums1,nums2,3);
        System.out.println(ret);
    }

Gracias por leer~~~

Supongo que te gusta

Origin blog.csdn.net/weixin_58850105/article/details/122754361
Recomendado
Clasificación