Estructura de datos búsqueda binaria DO (on)

contenido

1. Búsqueda binaria

 2. Busque la posición de inserción

3. Busque la primera y la última posición en una matriz ordenada

4. Busque el valor mínimo de la matriz rotada

5. Matriz de rotación de búsqueda II

6. Matriz de rotación de búsqueda (pregunta de la entrevista)

7. Encuentra el valor mínimo en una matriz rotada

8. Busque el valor mínimo en la matriz rotada II

9. Encuentra el número mínimo local en una matriz


1. Búsqueda binaria

Enlace de código de lete correspondiente:

704. Búsqueda binaria - LeetCode (leetcode-cn.com)

Tema Descripción:

Ideas para resolver problemas:

 

 Primero, calcule el subíndice de la posición media de acuerdo con el subíndice de la posición inicial de la matriz y el subíndice de la posición final, y luego compare el valor de la posición media con el valor a buscar.

En esta imagen:

Dado que el elemento que se va a encontrar, 20, es mayor que el elemento del medio, 12, ubique nuevamente el elemento del medio de la mitad derecha de la matriz:

 Acabo de encontrar el elemento 20.

Si la longitud del arreglo es N, entonces la complejidad del tiempo es O(log N) y la complejidad del espacio es O(1).

Código correspondiente:

class Solution {
public:
    int search(vector<int>& nums, int target) {
          int left=0;
          int right=nums.size()-1;
          int ans=-1;
          while(left<=right){
            int mid=(left+right)>>1;//求中点
            if(nums[mid]==target){//找到了
                ans=mid;
                break;
            }
            else if(nums[mid]<target){
                left=mid+1;
            }
            else{
                right=mid-1;
            }

          }
        return ans;

    }
};

 2. Busque la posición de inserción

35. Buscar ubicación de inserción - LeetCode (leetcode-cn.com)

 Tema Descripción:

Ideas para resolver problemas:

La idea de esta pregunta es muy similar a la pregunta anterior, solo necesitas encontrar el elemento más a la izquierda que sea mayor o igual que el objetivo, el flujo del algoritmo es el siguiente:

1. Encuentra el punto medio y compara el objetivo

2. Si el valor de la posición final es mayor o igual que el objetivo, corte y ajuste la derecha

3. Si el valor de la posición final es menor que el objetivo, corte la izquierda.

4. Si el objetivo es más que todos los elementos de la matriz, significa que se inserta al final de la matriz.

Código correspondiente:

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
            int index=-1;//记录答案下标
            int left=0;
            int right=nums.size()-1;
              while(left<=right){

                int mid=(left+right)>>1;
                if(nums[mid]>=target){//大于等于往左边走找到最左边大于等于target的位置
                    index=mid;
                    right=mid-1;
                }
                else{
                    left=mid+1;
                }
            }
            return index==-1?nums.size():index;//如果上面没有更新过答案说明插入位置在数组的末尾
    }
};

3. Busque la primera y la última posición en una matriz ordenada

Enlace de código de lete correspondiente:

34. Encuentre la primera y la última posición de un elemento en una matriz ordenada: LeetCode (leetcode-cn.com)

 Tema Descripción:

 Ideas para resolver problemas:

1. Use la búsqueda binaria para encontrar la posición más a la derecha más pequeña que el objetivo

2. +1 la posición devuelta para ver si ha cruzado el límite o el valor no es igual al objetivo

3. Encuentre la posición más a la derecha más pequeña que target+1, es decir, target.

Código correspondiente:

class Solution {
public: 
       int FindIndex(vector<int>&nums,int target){
           int left=0;
           int right=nums.size()-1;
           int ans=-1;//记录答案找比target小的最右的位置
           while(left<=right){
               int mid=(left+right)>>1;
               if(nums[mid]<target){//只要比target要小就记录答案
                      left=mid+1;
                      ans=mid;
               }
               else{
                     right=mid-1;
               }
           }
           return ans;
       }
    vector<int> searchRange(vector<int>& nums, int target) {
                int L=FindIndex(nums,target)+1;//在比target小的最右边的位置在加个1
                
                if(L==nums.size()||nums[L]!=target){//如果已经越界了或者这个位置的值不是target
                    return {-1,-1};
                }
                return {L,FindIndex(nums,target+1)};//找到比target+1小的最右边的数即target

    }
};

4. Busque el valor mínimo de la matriz rotada

Enlace de código de lete correspondiente:

153. Encuentre el valor mínimo en una matriz ordenada rotada - LeetCode (leetcode-cn.com)

Tema Descripción:

Ideas para resolver problemas:

 Ideas para resolver problemas:

1. Defina una variable para registrar la respuesta

2. Tome el punto medio y compare el valor de la izquierda. Si el valor de la izquierda es menor o igual que el valor de la derecha, significa que la izquierda está ordenada. Al juzgar si el objetivo está en este intervalo, si está en right=mid-1, de lo contrario, left=mid+1.

3. Si el lado izquierdo está fuera de orden, significa que el lado derecho está en orden, y se hace el mismo juicio si está en este intervalo, si es izquierdo = medio + 1, de lo contrario derecho = medio-1.

Tome el siguiente ejemplo:

 

De acuerdo con la figura anterior, podemos ver intuitivamente una regla, ¿cómo juzgar si está perturbada por la rotación? La condición previa para el orden ascendente normal es primer elemento <= último elemento, y la condición para el orden desordenado es: primer elemento > último elemento

Luego continúe investigando la ley de la matriz desordenada, es decir, el orden en el desorden, ¿cómo entenderlo?

 

 Código correspondiente:

class Solution {
public:
    int search(vector<int>& nums, int target) {
         if(nums.empty())//如果为空
          return -1;
        int left=0;
        int right=nums.size()-1;
        int ans=INT_MAX;
        while(left<=right){
            int mid=(left+right)/2;
            if(nums[mid]==target)
              ans=mid;
            if(nums[mid]>=nums[left]){//如果左边有序
                if(target>=nums[left]&&target<=nums[mid]){//如果在这个区间里面
                    right=mid-1;
                }

                else{
                    left=mid+1;
                }

            }
            else{//右边有序
                
                if(target>=nums[mid]&&target<=nums[right]){
                         left=mid+1;
                }

                else{
                    right=mid-1;
                }
                 
                }
        }
        return  ans==INT_MAX?-1:ans;
    }
};

5. Matriz de rotación de búsqueda II

Enlace de código de lete correspondiente:

81. Matriz ordenada de rotación de búsqueda II - LeetCode (leetcode-cn.com)

Tema Descripción

Ideas para resolver problemas:

La diferencia entre esta pregunta y la pregunta anterior es que puede haber elementos repetidos, cuando los valores de la izquierda y la derecha son iguales, no podemos juzgar el orden de los dos intervalos [left,,mid] y [mid,right ]. Entonces, debemos eliminar la parte de la derecha, cuyo valor es igual al valor de la izquierda, y seguir la idea de la pregunta anterior.

Código correspondiente:

class Solution {
public:
    bool search(vector<int>& arr, int target) {
        int l = 0, r = arr.size() - 1;
        int ans = INT_MAX;
          while(l < r && arr[l] == arr[r]){
                r--;
            }
        while(l <= r){
          
            int mid = (l+r)/2;
            if(arr[mid] == target){//相等找到了
                ans = mid;
                break;
            }
            if(arr[l] <= arr[mid]){//左边有序
                if(arr[l] <= target && target <= arr[mid]){
                    r = mid - 1;
                }else {
                    l = mid + 1;
                }
            }else {//右边有序
                if(arr[mid] <=  target && target <= arr[r]){
                    l = mid + 1;
                }else {
                    r = mid - 1;
                }
            }
        }
        return ans == INT_MAX ? false : true;
    }
};

6. Matriz de rotación de búsqueda (pregunta de la entrevista)

Enlace de código de lete correspondiente:

Pregunta de la entrevista 10.03 Búsqueda de matrices de rotación: LeetCode (leetcode-cn.com)

Tema Descripción:

 Ideas para resolver problemas: es básicamente lo mismo que la pregunta anterior, pero la respuesta debe actualizarse.

Código correspondiente:

class Solution {
public:
    int search(vector<int>& arr, int target) {
              int l = 0, r = arr.size() - 1;
            while(l < r && arr[l] == arr[r]){//删除右边和左边值相等都部分
                r--;
            }
        int ans = INT_MAX;
        while(l <= r){
        
            int mid = ((r - l) >> 1) + l;
            if(arr[mid] == target){//相等
                ans = min(ans, mid);//更新下标
            }
            if(arr[l] <= arr[mid]){//[l,mid]有序
                if(arr[l] <= target && target <= arr[mid]){
                    r = mid - 1;
                }else {
                    l = mid + 1;
                }
            }else {//[mid,r]有序
                if(arr[mid] <=  target && target <= arr[r]){
                    l = mid + 1;
                }else {
                    r = mid - 1;
                }
            }
        }
        return ans == INT_MAX ? -1 : ans;
    }
};

7. Encuentra el valor mínimo en una matriz rotada

Enlace de código de lete correspondiente:

153. Encuentre el valor mínimo en una matriz ordenada rotada - LeetCode (leetcode-cn.com)

Tema Descripción:

 Ideas para resolver problemas:

Queremos encontrar el valor mínimo en la matriz. Primero usamos binario para encontrar el valor del elemento medio y lo comparamos con el último valor. Si el valor del punto medio es menor que el valor del último elemento, let right= mid en el segundo párrafo, de lo contrario, left = mid + 1. Sabiendo left = mid encuentra el elemento más pequeño. 

Código correspondiente:

class Solution {
public:
    int findMin(vector<int>& nums) {
        if(nums.size()==1)//只有一个元素
          return nums[0];
        if(nums[0]<nums.back())//本来就是有序的
          return nums[0];
        int left=0;
        int right=nums.size()-1;
        while(left<right){
            int mid=(left+right)>>1;//取中点
            if(nums[mid]<nums.back()){//说明在第二段
                right=mid;
            }
            else{
                left=mid+1;
            }
        }
        return nums[left];
    }
};

8. Busque el valor mínimo en la matriz rotada II

Enlace de código de lete correspondiente:

154. Encuentre el valor mínimo en una matriz ordenada rotada II - LeetCode (leetcode-cn.com)

Tema Descripción

 Ideas para resolver problemas:

La idea de esta pregunta es básicamente la misma que la pregunta anterior, excepto que habrá elementos iguales a la izquierda y a la derecha, y será imposible determinar si está del otro lado, por lo que debemos elimine la parte de la derecha, cuyo valor es igual al valor de la izquierda, y es lo mismo que la pregunta anterior.

Para el código:

class Solution {
public:
    int findMin(vector<int>& nums) {
           if(nums.size()==1)
             return nums[0];
       
            int left=0;
            int right=nums.size()-1;

            while(left<right&&nums[left]==nums[right])//将相等的部分去除掉
                   right--;
           if(nums[left]<=nums[right])
              return nums[left];
            while(left<right){
                int mid=(left+right)/2;
                if(nums[mid]<nums[0]){//说明在在旋转的拿一部分
                    right=mid;
                }
                else{
                    left=mid+1;
                }
            }
            return nums[left];//返回结果

    }
};

9. Encuentra el número mínimo local en una matriz

Encuentre un mínimo local en una matriz

Tema Descripción:

 Ideas para resolver problemas:

Divida según la definición del tema. Consulte el código para obtener más detalles:

#include<iostream>
#include<vector>
using namespace std;
int GetMin(vector<int>&arr){
    int n=arr.size();
    //边界条件
    if(arr.size()==1){
        return 0;
    }
    if(arr[0]<arr[1]){
        return 0;
    }
    if(arr[n-1]<arr[n-2]){
        return n-1;
    }
    int left=0;
    int right=n-1;
    while(left<right-1){//剩下两个数最后所以是left<righ-1
        int mid=(left+right)>>1;
        if(arr[mid]<arr[mid-1]&&arr[mid]<arr[mid+1]){//找到了
             return mid;
        }
        else{
            if(arr[mid]>arr[mid-1]){
                right=mid-1;
            }
            else{//arr[mid]>arr[mid+1]找到一边
                left=mid+1;
            }
        }
    }
    return arr[left]<arr[right]?left:right;//比较
    
}
int main(){
    int n;
    cin>>n;
    vector<int>arr(n);
    for(int i=0;i<n;i++){
        cin>>arr[i];
    }
    cout<<GetMin(arr);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/qq_56999918/article/details/123585575
Recomendado
Clasificación