Comparaison tas + objet de structure de données version java

 Le premier jour de 2022, tigre ah tigre ah, je souhaite à tous une année prospère du tigre ! ! ! Le premier blog de l'année est ici

teneur

1. Poser des questions

2. Comparaison des éléments

2.1 Comparaison des éléments

2.2 Comparaison des objets

3. Comparaison d'objets

3.1 Remplacer l'égal de la classe de base

3.2 Comparaison basée sur la classe d'interface Comparble

3.3 Comparaison basée sur un comparateur

3.4 Comparaison de trois méthodes

6. Le problème du tas restant de la dernière leçon

6.1 Problème TopK

6.2 Questions d'entrevue


1. Poser des questions

Dans le blog précédent, nous avons récompensé la file d'attente prioritaire. La file d'attente prioritaire a une exigence lors de l'insertion d'éléments : l'élément inséré ne peut pas être nul ou les éléments doivent pouvoir être comparés . Pour simplifier, nous insérons simplement le type Integer , la priorité Peut vous insérez des objets de type personnalisé dans la file d'attente ?
Nous allons jeter un coup d'oeil
①Lorsque l'élément inséré est nul : (Peu importe quand vous insérez null, une exception de pointeur nul sera signalée)

2. Comparaison des éléments 

2.1 Comparaison des types de base

En Java , les objets de types primitifs peuvent être directement comparés en taille.
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 Comparaison des objets

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. Comparaison d'objets

Dans certains cas, le contenu de l'objet doit être comparé. Par exemple, lorsqu'un objet est inséré dans la file d'attente prioritaire, le tas doit être ajusté en fonction du contenu de l'objet. Comment gérer cela ?

3.1 Remplacer l'égal de la classe de base

Remarque : lorsqu'un type personnalisé veut comparer si les deux sont identiques et ont le même contenu, assurez-vous de remplacer sa méthode equals

Modifiez le code pour :

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));

    }

Remarque : La routine générale pour remplacer les égaux est comme démontré ci-dessus
1. S'il pointe vers le même objet, retourne true
2. Si l'entrée est null , retourne false
3. Si le type d'objet entrant n'est pas Card , renvoyez false
4. Complétez la comparaison en fonction de l'objectif de réalisation de la classe Par exemple, tant que la couleur et la valeur sont identiques, on considère qu'il s'agit de la même carte
5. Notez que la comparaison d'autres types de référence nécessite également des égaux , comme la comparaison de costume ici
Bien que la méthode de remplacement de la classe de base equal puisse être comparée, le défaut est le suivant : equal ne peut être comparé qu'en fonction de l'égalité, et ne peut pas être comparé en fonction de supérieur ou inférieur à . v

3.2 Comparaison basée sur la classe d'interface Comparble

  Afin d'avoir la possibilité de comparer, implémentez l'interface Comparable ici et comparez les pièces spécifiées dont vous avez besoin (la valeur par défaut ici est la comparaison de petits tas)

code afficher comme ci-dessous:

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 Comparaison basée sur un comparateur

 code afficher comme ci-dessous:

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);
    }

Vous pouvez également utiliser les deux méthodes suivantes :

Méthode 1 : classe interne anonyme

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

Méthode ② : expression lambda


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

 3.4 Comparaison de trois méthodes

 compareTo est plus enclin aux classes

6. Le problème du tas restant de la dernière leçon

6.1 Problème TopK

Idée ① : triez le tout et affichez les 10 éléments les plus grands. (façon habituelle de penser)

Idée 2 : Utilisez le tas que vous venez d'apprendre

Idée ③ : a. Créez d'abord les 3 premiers éléments comme un petit tas racine
              b. Parce que le tas actuel est un petit tas racine, alors l'élément supérieur du tas doit être le plus petit des k premiers éléments. S'il y a un élément plus grand que l'élément supérieur du tas, il remplace l'élément supérieur du tas, et cet élément peut être l'un des topks. Au contraire, s'il s'agit d'un grand tas racine, ce n'est pas nécessairement
              C. Une fois l'élément supérieur du tas retiré, il sera à nouveau ajusté en un petit tas racine.


code afficher comme ci-dessous:

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));
    }
}

Problème de tri par tas :

Idées de résolution de problèmes : (la condition de fin est que la fin est 0)

① Ajustez le tas à un grand tas racine

②L'indice 0 peut être échangé avec le dernier élément non trié 

③fin--

④ Ajustez à nouveau le tas au gros tas racine

code afficher comme ci-dessous: 

  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 Questions d'entrevue

373. Trouver et les plus petites K paires de nombres - LeetCode (leetcode-cn.com) https://leetcode-cn.com/problems/find-k-pairs-with-smallest-sums/

sujet:

Étant donné deux tableaux d'entiers nums1 et nums2 dans l'ordre croissant, et un entier k.

Définissez une paire de valeurs (u,v) où le premier élément provient de nums1 et le deuxième élément provient de nums2 .

Trouver les k paires avec la plus petite somme (u1,v1), (u2,v2) ... (uk,vk) .

Idée de résolution de problème : (en fait, c'est aussi un problème topK, la différence est qu'il est remplacé par la plus petite somme des premiers k)

? ? ? la question c'est ça ? ? ? Comment mettre un ensemble de paires

PriorityQueue<Liste<Entier>>

code afficher comme ci-dessous:

  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);
    }

Merci d'avoir lu ~~~

Je suppose que tu aimes

Origine blog.csdn.net/weixin_58850105/article/details/122754361
conseillé
Classement