[Niuke.com – Top 101 Interviews, die man unbedingt machen muss] Binäre Suchfragen

Inhaltsverzeichnis

Suche im zweidimensionalen Array_NiukeTiba_Niuke.com (nowcoder.com)

Auf der Suche nach Peaks_NiukeTiba_Niuke.com (nowcoder.com)

Paare in umgekehrter Reihenfolge in einem Array_Niuke Topic_Niuke.com (nowcoder.com)

Die kleinste Zahl des gedrehten array_NiukeTiba_Niuke.com (nowcoder.com)


 

Suche im zweidimensionalen Array_NiukeTiba_Niuke.com (nowcoder.com)

Bedeutung der Frage:

In einem zweidimensionalen Array (jedes eindimensionale Array hat die gleiche Länge) wird jede Zeile in aufsteigender Reihenfolge von links nach rechts und jede Spalte in aufsteigender Reihenfolge von oben nach unten sortiert. Bitte vervollständigen Sie eine Funktion, geben Sie ein solches zweidimensionales Array und eine Ganzzahl ein und bestimmen Sie, ob das Array die Ganzzahl enthält.

[

[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]

]

Bei gegebenem Ziel = 7 wird „true“ zurückgegeben.

Bei gegebenem Ziel = 3 wird „Falsch“ zurückgegeben.

Datenbereich: Die Länge und Breite der Matrix erfüllen 0≤n,m≤5000, und die Werte in der Matrix erfüllen 0≤val≤10^9.
Fortgeschrittene: Raumkomplexität O(1), Zeitkomplexität O(n+ M)

[Eingabebeispiel] 7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]

[Ausgabebeispiel] wahr

Ideen zur Problemlösung:

Die Regel der Matrix besteht darin, dass sie von links nach rechts und von oben nach unten zunimmt.

Wählen Sie zum Vergleich a[row][col] in der oberen rechten Ecke der Matrix aus. Wenn target<a[row][col] ist, beweist dies, dass sich das Ziel links von der aktuellen Spalte befindet, und wir können nachschauen linke Matrix, um es zu finden;

Wenn Ziel>a[Zeile][Spalte], beweist dies, dass das Ziel unter der aktuellen Zeile liegt, und wir suchen in der Matrix unten;

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param target int整型 
     * @param array int整型二维数组 
     * @return bool布尔型
     */
    public boolean Find (int target, int[][] array) {
        // write code here
        int n = array.length;
        int m = array[0].length;
        int row = 0;//行
        int col = m-1;//列
        while(row < n && col >= 0){
            if(target == array[row][col]){
                return true;
            }else if(target > array[row][col]){
                row++;
            }else{
                col--;
            }
        }
    
        return false;
    }
}

Auf der Suche nach Peaks_NiukeTiba_Niuke.com (nowcoder.com)

Bedeutung der Frage:

Finden Sie bei einem gegebenen Array nums der Länge n den Spitzenwert und geben Sie seinen Index zurück. Das Array kann mehrere Peaks enthalten. In diesem Fall wird lediglich die Position eines beliebigen Peaks zurückgegeben.

1. Ein Spitzenelement bezieht sich auf ein Element, dessen Wert strikt größer ist als die angrenzenden Werte links und rechts. Streng größer oder gleich

2. Angenommen, nums[-1] = nums[n] = −∞

3. Für alle gültigen i gibt es nums[i] != nums[i + 1]

4. Können Sie dieses Problem mit der Zeitkomplexität O(logN) implementieren?

Datenreichweite:

1≤nums.length≤2×105 

−231<=nums[i]<=231−1

 Eingabebeispiel: [2,4,1,2,7,8,4]

Ausgabebeispiel: 1

 Ideen zur Problemlösung:

1. Heftige Aufzählung, solange sie größer als die vorherige Ziffer und größer als die nächste Ziffer ist, ist sie der Spitzenwert und wird direkt zurückgegeben.

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findPeakElement (int[] nums) {
        // write code here
        if(nums.length >= 2 && nums[0] > nums[1] || nums.length == 1){
            return 0;
        }
        if(nums.length >= 2 && nums[nums.length-2] < nums[nums.length-1]){
            return nums.length-1;
        }
        for(int i=1;i<nums.length-1;++i){
            if(nums[i] > nums[i-1] && nums[i] > nums[i+1]){
                return i;
            }
        }
        return -1;
    }
}

Lösungsidee 2:

Bei der binären Suche beträgt die Komplexität der Implementierungszeit O (Logn).

Genau wie bei der gewöhnlichen binären Suche wird zuerst die Mitte berechnet

Wenn nums[mid] > num[mid+1], bedeutet dies, dass mid wahrscheinlich der Spitzenwert ist und wir nach links gehen. Der Unterschied zur binären Suche besteht hier darin, dass beim Gehen nach links rechts = Mitte gilt. nicht Mitte 1, da Mitte möglich ist. Der Spitzenwert muss in der nächsten Durchlaufrunde verglichen werden.

Wenn nums[mid] <= nums[mid+1], bedeutet dies, dass mid+1 wahrscheinlich ein Spitzenwert ist. Wir gehen nach rechts, links = mid+1, weil mid kein möglicher Spitzenwert mehr ist. also kein Include

Nach mehreren Durchlaufrunden kann schließlich ein korrekter Spitzenwert im Intervall gefunden werden.

Wenn es monoton ansteigt, gehen Sie jedes Mal nach rechts, bis left=right=nums.length-1; wenn es monoton abnimmt, gehen Sie nach links, bis left=right=0

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findPeakElement (int[] nums) {
        // write code here
       if(nums.length == 1){
           return 0;
       }
       int left = 0;
       int right = nums.length -1;
       int mid;
       while(left < right){
            mid = (left + right) /2;
            if(nums[mid] > nums[mid+1]){
                //mid比下一位大,有可能是山峰,往左遍历
                right = mid;//注意这里right是赋值mid,因为mid可能是山峰,所以要包含他去寻找
            }else{
                //mid比它下一位小,mid+1有可能是山峰,向右走
                left = mid + 1;//从大的数开始往右查找
            }
       }
        return right;
    }
}

Paare in umgekehrter Reihenfolge in einem Array_Niuke Topic_Niuke.com (nowcoder.com)

Themenbeschreibung:

Zwei Zahlen in einem Array. Wenn die erste Zahl größer als die spätere Zahl ist, bilden die beiden Zahlen ein Paar in umgekehrter Reihenfolge. Geben Sie ein Array ein und ermitteln Sie die Gesamtzahl der Paare P in umgekehrter Reihenfolge im Array. Und geben Sie das Ergebnis von P modulo 1000000007 aus. Das heißt, der Ausgang P mod 1000000007


Datenbereich: Für 50 % der Daten ist die Größe ≤ 10 ^ 4.
Für 100 % der Daten ist die Größe ≤ 10 ^ 5

Die Werte aller Zahlen im Array erfüllen 0≤val≤10^9
 

Anforderungen: Raumkomplexität O(n), Zeitkomplexität O(nlogn)

[Eingabebeispiel][1,2,3,4,5,6,7,0]

[Ausgabebeispiel] 7

Problemlösungsidee 1: Doppelschleife, heftige Aufzählung, zeitliche Komplexität ist O(n^2), Laufzeitüberschreitung 

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int InversePairs (int[] nums) {
        // write code here
        int ans=0;
        for(int i =0; i<nums.length-1; ++i){
            for(int j=i; j< nums.length; ++j){
                if(nums[i] > nums[j]){
                    ans++;
                    ans %= 1000000007;
                } 
            }
        }
        return ans;
    }
}

Lösungsidee 2:

 Basierend auf der Zusammenführungssortiermethode kann beim Zusammenführen die Anzahl der aktuell generierten Paare in umgekehrter Reihenfolge direkt berechnet werden, wenn die Zahl rechts kleiner als die Zahl links ist.

import java.util.*;


public class Solution {
    int ans=0;
    public int InversePairs (int[] nums) {
        // write code here
        if(nums.length < 2){
            return 0;
        }
        mergeSort(nums,0,nums.length-1);
        return ans;
    }
    public void mergeSort(int[] nums,int left,int right){
        //分割点
        int mid = (left+right)/2;
        if(left < right){
            mergeSort(nums,left,mid);
            mergeSort(nums,mid+1,right);
            //合并
            merge(nums,left,mid,right);
        }
    }
    public void merge(int[] nums,int left,int mid,int right){
        //创建临时数组
        int[] arr = new int[right - left + 1];
        //临时数组下标起点
        int c = 0;
        int s = left;
        int l = left;
        int r = mid + 1;//左右数组的起始指针
        while(l <= mid && r <= right){
            //当左数组的元素小时,跳过
            if(nums[l] <= nums[r]){
                //放入临时数组
                arr[c] = nums[l];
                c++;
                l++;
            }else{
                //存在逆序对,统计
                arr[c] = nums[r];
                //逆序对个数,
                ans += mid+1 - l;
                ans %= 1000000007;
                c++;
                r++;
            }
        }
        //左子数组还有元素,放入
        while(l <= mid){
            arr[c++] = nums[l++];
        }
        while(r <= right){
            arr[c++] = nums[r++];
        }
        //临时数组放入数组原位置
        for(int num: arr){
            nums[s++] = num;
        }
    }
}

Die kleinste Zahl des gedrehten array_NiukeTiba_Niuke.com (nowcoder.com)

Themenbeschreibung:

Es gibt ein nicht absteigendes Array der Länge n, beispielsweise [1,2,3,4,5]. Drehen Sie es, dh verschieben Sie die ersten Elemente eines Arrays an das Ende des Arrays, um es in ein gedrehtes Array umzuwandeln Array. Beispielsweise wird es zu [3,4,5,1,2] oder [4,5,1,2,3]. Bitte fragen Sie, ob bei einem solchen rotierten Array der Mindestwert im Array ermittelt werden kann.

Datenbereich: 1≤n≤10000, Wert eines beliebigen Elements im Array: 0≤val≤10000

Anforderungen: Raumkomplexität: O(1), Zeitkomplexität: O(logn)

[Eingabebeispiel][3,4,5,1,2]

【Ausgabebeispiel】1 

Ideen zur Problemlösung:

Um ein nicht absteigendes Array zu drehen, verwenden wir die binäre Suche, um das Array in zwei Unterarrays aufzuteilen. Es muss ein Unterarray geben, das nicht in der richtigen Reihenfolge ist.

Beispielsweise wird [left, right] in [left, mid] [mid, right] unterteilt. Wenn nums[left] > nums[mid], beweist dies, dass das Intervall [left, mid] nicht mehr den Anforderungen von a entspricht Nicht absteigendes Array, also dieses Intervall Nach der Rotation wird es ungeordnet und der Mindestwert wird hier gefunden.

Wenn sie gleich sind, grenzen Sie den Bereich ein und fahren Sie mit der Suche fort.

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int minNumberInRotateArray (int[] nums) {
        // write code here
        int left = 0;
        int right = nums.length-1;
        while(left < right){
            int mid = (left + right) / 2;
            if(nums[mid] > nums[right]){ //右子数组无序
                left = mid + 1;
            }else if(nums[mid] < nums[right]){//左子数组无序
                right = mid;
            }else{
                //如果是相等的话,缩小范围
                right--;
            }
        }
        return nums[left];
    }
}

 

Je suppose que tu aimes

Origine blog.csdn.net/qq_37998848/article/details/133499885
conseillé
Classement