1.1.2 Tableaux - Trouver la première et la dernière position d'un élément dans un tableau trié (Leetcode 34)

Trouver la première et la dernière position d'un élément dans un tableau trié

1. Sujet

Lien Leetcode
Soit un tableau d'entiers nums dans l'ordre croissant, et une valeur cible target. Découvrez où dans le tableau la valeur cible donnée commence et se termine.

Si la valeur cible cible n'existe pas dans le tableau, renvoie [-1, -1].

Avancé:

Pouvez-vous concevoir et implémenter un algorithme de complexité temporelle O(log n) pour résoudre ce problème ?

Exemple 1:

Entrée : nombres = [5,7,7,8,8,10], cible = 8
Sortie : [3,4]

Exemple 2 :

Entrée : nombres = [5,7,7,8,8,10], cible = 6
Sortie : [-1,-1]

Exemple 3 :

Entrée : nombres = [], cible = 0
Sortie : [-1,-1]

indice:

  • 0 <= nombres.longueur <= 105
  • -109 <= nombres[i] <= 109
  • nums est un tableau non décroissant
  • -109 <= cible <= 109

2. Idée

trois conditions :

  • la cible n'est pas dans la plage du tableau
  • la cible est dans la plage du tableau, mais la cible n'existe pas dans le tableau
  • la cible est dans la plage du tableau et la cible existe dans le tableau

Méthode de résolution :

  1. Trouver les limites gauche et droite avec la bissection
  • Limite droite : le premier indice supérieur à la cible
  • Limite gauche : le dernier indice inférieur à la cible
  1. Trois cas sont traités selon les limites gauche et droite
  • Cas 1 : la cible est supérieure à la valeur maximale du tableau, pas de limite droite ; la cible est inférieure à la valeur minimale du tableau, pas de limite gauche
  • Cas 2 : lors d'un autre traitement
  • Cas 3 : Limite droite - Limite gauche > 1

3. Mise en œuvre du code

class Solution {
    
    
public:
    vector<int> searchRange(vector<int>& nums, int target) {
    
    
        int leftBorder = getLeftBorder(nums, target);
        int rightBorder = getRightBorder(nums, target);
        // leftBorder、rightBorder初始化为-2

        // 情况一:target不在数组范围内
        if(leftBorder == -2 || rightBorder == -2) return {
    
    -1, -1};
        // 情况三:target在数组范围内,且数组中存在target
        if(rightBorder - leftBorder > 1) return {
    
    leftBorder + 1, rightBorder - 1};
        // 情况二:target在数组范围内,但数组中不存在target
        return {
    
    -1, -1};

    }

private:
    int getLeftBorder(vector<int>& nums, int target) {
    
    
        int left = 0;
        int right = nums.size() - 1;
        int leftBorder = -2;

        while(left <= right){
    
    
            int middle = left + (right - left) / 2;
            if(nums[middle] < target){
    
    
                left = middle + 1;
            }else{
    
     // 注意leftBorder是通过right得到,right记录的是大于等于target的下标
                right = middle - 1;
                leftBorder = right;
            }

        }
        return leftBorder;
    }

    int getRightBorder(vector<int>& nums, int target) {
    
    
        int left = 0;
        int right = nums.size() - 1;
        int rightBorder = -2;

        while(left <= right){
    
    
            int middle = left + (right - left) / 2;
            if(nums[middle] > target){
    
    
                right = middle - 1;
            }else{
    
     // 注意rightBorder是通过left得到,left记录的是小于等于target的下标
                left = middle + 1;
                rightBorder = left;
            }

        }
        return rightBorder;
    }
};

4. Résumé

  • compréhension des frontières gauche et droite

Guess you like

Origin blog.csdn.net/weixin_46297585/article/details/123196401