Algorithm Description:
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it wocould be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6]
, 5 → 2
[1,3,5,6]
, 2 → 1
[1,3,5,6]
, 7 → 4
[1,3,5,6]
, 0 → 0
Leetcode link: https://oj.leetcode.com/problems/search-insert-position/
Algorithm parsing:
This algorithm requires: given an ordered array and a target value, you can quickly find the position of the target value in the ordered array (that is, the index. Note that the index of the array starts from 0 ), in addition, this array can be considered as having no repeated numbers. Through analysis, we know that a valid index value is returned regardless of whether the target value exists in the given array, and the array after inserting the target value is still ordered.
I like everything from simple to complex. So I first thought of the sequential search algorithm, traversing the array from the past to the next until the position is reached. The solution is as follows:
class Solution {public: int searchInsert(int A[], int n, int target) { int i = 0; while((target > A[i]) && (i < n)) { i++; } if (i == n) { return n; } else { return i; } }};
Performance analysis:
According to the above solution, the AC can pass, as shown in the result:
From the analysis results, we can see that this solution has tested 62 cases and runs a total of 52 Ms. There is no improvement for this method! After careful analysis, in fact, some critical points do not require loops. For example, when the target value is smaller than the minimum value in the array (of course, this condition does not affect the performance because the loop is not executed ); when the target value is larger than the maximum value in the array, the array is traversed. Therefore, as long as the critical conditions are processed separately and the cycle ends early, the performance can be improved. The improved solution is as follows:
class Solution {public: int searchInsert(int A[], int n, int target) { if (target <= A[0]) { return 0; } else if (target == A[n - 1]) { return n - 1; } else if (target > A[n - 1]) { return n; } int i = 1; while((target > A[i]) && (i < n)) { i++; } return i; }};
The AC analysis result is as follows:
From the results, we can see that 62 cases have been resolved, and the time has been shortened to 40 ms. Although the performance of a specific case may not be improved, however, if your application requires a lot of use of this algorithm, the performance improvement will be extremely impressive. Other implementation ideas:
In fact, this algorithm is the application of the search algorithm. The above method is the application of the sequential search algorithm. Of course, you can use the half-lookup method to implement this algorithm. The solution is as follows:
Class solution {public: int searchinsert (int A [], int N, int target) {If (target <= A [0]) // if the target is smaller than the minimum number, {return 0;} else if (target> A [n-1]) // if the target is greater than the maximum number, {return N;} int low = 0; int high = N; int middle = (low + high)/2; while (low
So what is the performance of semi-query? We know that the time complexity of sequential search is O (n), while that of semi-query is O (log2 (n )), it is reasonable to say that the performance of half-lookup is much better than that of sequential lookup. What is the actual performance! Let's take a look at the AC results, as shown below:
From the result of AC, we can see that the time is still 40 ms. Why? This algorithm only relies on the half-lookup method. In fact, the search algorithm does not require arrays to be ordered, and the performance of the half-lookup is the highest when the order is unordered. Of course, there are other factors, for example, the characteristics of the case in AC.
Python solution: the python solution for sequential query is as follows:
class Solution: # @param A, a list of integers # @param target, an integer to be inserted # @return integer def searchInsert(self, A, target): length = len(A) if target > A[length - 1]: return length; elif target <= A[0]: return 0; i = 1; while target > A[i]: i += 1 return i
The AC result is as follows:
Python half-lookup implementation solution:
class Solution: # @param A, a list of integers # @param target, an integer to be inserted # @return integer def searchInsert(self, A, target): length = len(A) if target > A[length - 1]: return length elif target <= A[0]: return 0 low = 0 high = length middle = (low + high) / 2 while low < high: if target == A[middle]: return middle elif target > A[middle]: low = middle + 1 else: high = middle middle = (low + high) / 2 if low == high: if target > A[low]: return low + 1 else: return low
The AC result is as follows:
Here, I will only give the results. Let's take a look at the results and we will find some surprises !!!
Leetcode-search insert position