Elementary Algorithm (3): Explanation and implementation of dichotomy (C language), and the application of dichotomy in ordered arrays

Series Article Directory

 Chapter 1  Elementary Algorithms (1): Understanding Time Complexity Through Simple Sorting Algorithms

 Chapter 2  Preliminary Algorithm (2): A detailed introduction to the details and time complexity of insertion sorting

 Chapter 3 Elementary Algorithms (3): Explanation and implementation of dichotomy, and the application of dichotomy in ordered arrays


Table of contents

Series Article Directory

foreword

1. Explanation and implementation of dichotomy (C language)

1.1 Why use binary search in an ordered array?

1.2 Explanation of binary search:

 1.3 Code implementation of dichotomy:

2. Application of dichotomy (not only in ordered arrays)

2.1 General usage

 2.2 Unconventional practice (performed in an unnecessary array)

Summarize


foreword

       Wow, it's the third chapter in a blink of an eye. In the first two chapters (if you want to read the content of the first two chapters, please click the link of the series of article catalogs) , we mainly explained the sorting algorithm with a time complexity of O(N^2) ( bubble sort , selection sort , insertion sort ), I don't know what you think?

       In this chapter, we mainly talk about the use of the dichotomy method and three programming questions about the dichotomy method to break everyone's thinking that the dichotomy method can only be used in ordered arrays .


1. Explanation and implementation of dichotomy (C language)


1.1 Why use binary search in an ordered array?


       Generally, we look up a number in an ordered array . If we look up one by one according to the amount of data , sometimes it will be very fast, and sometimes it will be very slow! This is more troublesome, so we can't use one by one to find.

       Why is it sometimes fast and sometimes slow? Suppose we now have an ordered array (1,2,3,4,5,6,7,8,9,10,11,12,13), if you want to find 1 , you only need to traverse One bit is enough; but if you want to find 13 , you need to traverse the entire array .

       At this point, the array to be searched is an ordered array , and we can use the characteristics of ordered arrays to use binary search to find the number we are looking for.


1.2 Explanation of binary search:


       In the introduction above, it is said that binary search is used in an ordered array, so how is binary search implemented?

The basic idea  of ​​binary search is: first find the middle number and compare it with the number to be searched , and then divide the situation :

       1) If it is smaller than the number to be searched, then discard the left half of the number , find the middle number on the right half of the number and compare it with the number to be found , and repeat this process ;

       2) If it is larger than the number to be searched, then discard the right half of the number , find the middle number on the left half of the number and compare it with the number to be searched , and repeat this process ;

       Finally , until the last number is found .

       Next, estimate the time complexity of binary search, and use the worst data for calculation. Because half of the numbers are discarded in one code flow , the time complexity is O(logN) .


 1.3 Code implementation of dichotomy:


       After the detailed analysis above, the editor feels that the judges have fully understood the idea of ​​the dichotomy , so next, let's implement the dichotomy with the editor !

The code to implement the dichotomy is as follows:

    int left = 0;
    int right = n - 1;
    while (left <= (right - 1)){     //判断条件是左边指向的位置大于右边指向的位置
        int mid = (left + right) / 2;//中点的位置要随时更新,以便求出最新的中点坐标
        if(k > arr[n - 1])      //如果要查找的数大于数组的最后一个数时,则不需要继续查找
            break;
        if (arr[mid] == k){
            right = mid;
            if(arr[mid - 1] < arr[mid])  //与中间数进行比较
                ans = mid;
        }
        if(arr[mid] > k)     //随时更新中点坐标
            right = mid;  
        if(arr[mid] < k)
            left = mid;
    }

2. Application of dichotomy (not only in ordered arrays)


2.1 General usage


       Above we have searched for a certain number in an ordered array . Next, we will write a variant: find a certain position

Topic: You need to input an n, a number k, and then input an array arr with a length of n sizes, and then you need to find the leftmost position on arr that satisfies >=K, and output this position, if this position does not exist Just output -1.

      Seeing this question, my first reaction is to traverse the ordered arrayas long as the first number is found to be equal to k, it is the position we are looking for , then this method is the same as the one written above The same thinking as the first question , but sometimes very slow. Sometimes very quickly .

       In this article, we have learned the dichotomy, and we must use the dichotomy to solve problems. The basic idea is: first find the middle number and compare it with the number you want to find , and then divide the situation :

       1) If it is smaller than the number to be searched, the leftmost position of >=K should be on the right , then discard the left half of the number , find the middle number in the right half of the number and compare it with the number to be searched , and repeat this process ;

       2) If the number to be searched is equal to or greater than the number to be searched, the leftmost position of >=K should be on the right , then discard the right half of the number , mark it if it is equal to k, and then find the middle number in the left half of the number that matches the number to be searched Numbers are compared and this process is repeated ; finally, the entire array is traversed to find the first marked number .

       Finally , until the last >=K number is found .

The code to implement the topic is as follows:

int main()
{
	int n = 0, k = 0;
	scanf("%d %d", &n, &k);
	int a[1000000];
	for (int i = 0; i < n; i++)
		scanf("%d", &a[i]);
	int left = 0;
	int right = n - 1;
	int mid = 0;
	int reslut = -1;    //因为如果找不到,就输出-1
	while (left <= right){
		mid = (left + right) / 2;
		if (a[mid] >= k){
			reslut = mid;
			right = mid - 1;
		}
		else
			left = mid + 1;
	}
	printf("%d\n", reslut);
	return 0;
}

 2.2 Unconventional practice (performed in an unnecessary array)


       Can dichotomy really only work in sorted arrays? After the editor learned about this topic, I was also taken aback! The answer is yes!

       Next, follow the steps of the editor to learn! Look at this topic: The local minimum problem .

The concept of local minimum: 1) The number at position 0 in the array is smaller than the number at position 1 ;

                             2) The number atposition N-1in the arraysmallerthe number atposition N-2;

                             3) The number atthe i-th positionin the arraysmallerthe numbers atboth sides.

Question: Given an unordered array arr, it is known that any two adjacent numbers in arr are not equal, you only need to return the position where any local minimum occurs in arr, and output -1 if there is no such position.

       The editor can analyze and get:

       First judge the number at position 0 and the number at position 1, and then judge the number at position N-1 and the number at position N-2. If neither of these two situations is true, then there must be a decline at the beginning, and an increase at the end , and because every two numbers in the array are different, there must be a local minimum in 1 to N-2 .

       Next, we can use dichotomy to discard numbers. Find the number in the middle position and compare it with the numbers on both sides . If both are less than, return the number in the middle position; if one side is not less than, discard half and continue searching in the other half.

The code to implement the topic is as follows:

int main() {
    int n = 0;
    scanf("%d", &n);
    int a[100000];
    for (int i = 0; i < n; i++) {
        scanf("%d", a + i);
    }
    int left = 0;
    int right = n - 1;
    int mid = -1;
    if (n == 1 || a[0] < a[1]) {
        printf("%d\n", 0);
        return 0;
    }
    else if (a[n - 1] < a[n - 2]) {
        printf("%d\n", n - 1);
        return 0;
    } else {
        while (left <= right) {
            mid = (left + right) / 2;

            if (a[mid] > a[mid - 1]) {
                right = mid - 1;
            }
            else if (a[mid] > a[mid + 1]) {
                left = mid + 1;
            } else {
                //flag = 1;
                printf("%d\n", mid);
                return 0;
            }
        }
    }
    return 0;
}

Summarize

       The above is what I want to talk about today. This article introduces the dichotomy and its application in unordered arrays. In a few days, the editor will write some exercises about the dichotomy. I hope you can comment after reading it. Thank you!

Guess you like

Origin blog.csdn.net/2301_77868664/article/details/131977184