leetcode LCR 173. Roll Call

Code:

class Solution {
    public int takeAttendance(int[] records) {
        int left=0,right=records.length-1;
        while (left<right){
            int mid=left+(right-left)/2;

            if(mid==records[mid]){
                left=mid+1;
            }else {
                right=mid;
            }
        }

        if(left==records[left]){
            return left+1;
        }else {
            return left;
        }
    }
}

answer:

        There are many solutions to this problem, but most of the solutions have a complexity of O(N). Here we introduce an O(log N) method, the dichotomy method

        The meaning of the question is very simple. It is introduced directly through records = 0, 1, 2, 4, 5. We mark the subscript corresponding to each data. It is easy to find that the array can be divided into two intervals. The left interval The subscripts and values ​​are equal, and the values ​​and subscripts in the right interval are not equal.

        The missing data is 3. We can easily find that 3 is the subscript of the left boundary of the right interval, so our goal is to find the subscript of the left boundary of the right interval.

【0        1        2】【4        5】

   0         1        2       3        4

        We arbitrarily pick a number records[i]. When the value of records[i] is equal to the subscript, it means that records[i] is in the left interval. There is no result we want in the left interval, so we can boldly remove records[i] ] and the data on the left of records[ i ]. When the value of records[ i ] is different from the subscript, it means that the number is in the right range. We can boldly remove the data on the right of records[ i ] (records[ i ] cannot be removed. Because we are not sure whether records[i] is the left boundary we are looking for)

        From the above analysis, we can see that this question has a two-stage nature, and part of the data can be removed according to certain conditions, so we can use the dichotomy method to solve this problem

        Still using the above data for simulation

        Let the L and R pointers point to both ends of the array, and calculate the midpoint mid = L + (R - L)/2 = 2. At this time, records[mid] =mid, so in the left interval, we can let L = mid +1

【0        1        2】【4        5】

   0         1        2       3        4

   L                  mid              R

        ​ ​ ​ Then calculate the midpoint mid = L + (R - L)/2 = 3, at this time records[mid]! = mid, so in the right interval, let R = mid

【0        1        2】【4        5】

   0         1        2       3        4

                                 L        R

                               mid

        When L and R meet, we get the result we are looking for

【0        1        2】【4        5】

   0         1        2       3        4

                                 L        

                                 R

        Please note a special case. When the input records = 0, 1, 2, 3, 4, the corresponding subscripts are also 0, 1, 2, 3, 4. At this time, the subscripts and values ​​are always equal. So it is always in the left interval, which will cause that when L and R meet at the last data 4 of the array, the corresponding subscript is also 4, but what we want to fill is 5, so we need to judge, when L and R When the pointers meet, if records[L] == L, return L +1, otherwise return L

Guess you like

Origin blog.csdn.net/q322359/article/details/135004530