This is the 28th day of my participation in the August Challenge
Binary Search is also called Binary Search, which is a highly efficient Search method.
Binary search idea is very simple, algorithm ideas written below, do not know how to take a look (of course, if it is zero based advice or first go back to see what is binary search, learn to understand and then come back to see), understand do not need to see, test is not ideas, the focus is the application.
First of all, assuming that the elements in the table are arranged in ascending order, compare the keywords recorded in the middle of the table with the search keywords. If the two are equal, the search succeeds. Otherwise, the middle position record is used to divide the table into the front and back two sub-tables. If the key word of the middle position record is greater than the search key word, the former sub-table is further searched; otherwise, the latter sub-table is further searched. Repeat the above process until you find a record that meets the criteria, so that the search succeeds, or until the child table does not exist, at which point the search fails.
What I see is left god’s algorithm class, Left Cheng Yun teacher. In fact, I didn’t understand binary search before, it’s just finding numbers in ordered arrays, it’s faster than sequential search. But after watching The lecture on Left God, we found that binary lookup can be used not only for ordered arrays, but also for unordered arrays in certain cases.
So let’s do a couple of problems. Mention is very simple, the code is very simple, I will not analyze each sentence, you can see from beginning to end to understand the small white level of knowledge.
Apply to an unordered array
Given an unordered array arr, it is known that the values of any two adjacent elements are not the same. Please return any local minimum position. Locally minimal locations are:
- If arr[0]
- If AR [n-1] (the rightmost number of ARr) is less than ARr [n-2], then position n-1 is also the locally smallest position.
- If position I is neither the leftmost nor the rightmost. So as long as arr[I] is less than both the left and right sides of the position (arr[i-1] and arr[I +1]), then position I is also a locally smallest position.
D) to find a local minimum. In other words, you just have to find the minimum of some part. Here are some examples:
Enter the sample | The output sample |
---|---|
,2,3,1,2,3 [1] | 1 |
,2,3,1,2,0 [3] | 0 |
[6, 2, 3, 5, 2, 3] | 2 (2 to the left of 3) or minus 5 |
,4,3,1,0,3 [6] | 0 |
The output of the third sample above depends on your code. That’s output 2, as I’ve written it. Because we’re looking for local minima. When the median is larger than both sides, you can return either side, and I’m going to return the left side by default.
function min(a) {
let length = a.length
if (length === 0) { / / array is empty
return -1
} else {
let low = 0
let high = length - 1
let mid
if(low === high || a[0] < a[1]) {Arr [0]
return 0
}else if (a[length - 1] < a[length - 2]) {
return length - 1
} else {
while (low <= high) { / / dichotomy
mid = Math.floor(low + (high - low) / 2) // round down
if (a[mid] < a[mid + 1] && a[mid] < a[mid - 1]) {
return mid
} else if (a[mid] > a[mid - 1]) {
high = mid - 1
} else {
low = mid + 1
}
}
}
}
}
Copy the code
Note: I used low + (high-low)/2 instead of (low + high)/2 in the code because this prevents overflow if the array is too large.
Application in ordered repeating array
1
Given an ordered array arr and an integer num find the leftmost position in arr where the number num appears.
function find(a, num) {
let res = -1
if (a.length === 0) { // The array is empty
return res
}
let right = a.length - 1
let mid
let left = 0
while (left <= right) {
if (a[0] === num) { //a[0] is the number to find
return res = 0
} else {
while (left <= right) {
mid = Math.floor(left + (right - left) / 2)
if (a[mid] === num && a[mid] > a[mid - 1]) {
res = mid
break // You must write, otherwise the loop is endless
} else if (a[mid] < num) {
left = mid + 1
} else {
right = mid - 1}}return res
}
}
}
Copy the code
2
Given an ordered array arr with no repeating elements, find the leftmost position that satisfies the condition arr[I]== I. If the number at all positions does not satisfy the condition, -1 is returned.
function find(arr) {
let res = -1
if (arr.length === 0 || arr[0] > arr[length - 1] || arr[length - 1] < 0) {
Arr [I]= I; arr[I]= I; arr[I]= I
return res
} else {
let left = 0,
right = arr.length - 1,
mid = left + (right - left) / 2
while (left <= right) {
mid = Math.trunc(left + (right - left) / 2)
if (arr[mid] < mid) {
left = ++mid
} else if (arr[mid] > mid) {
right = --mid
} else {
res = mid
right = --mid
}
}
return res
}
}
Copy the code
Loop through the array to find the maximum/median
1
Given an ordered loop array arR, return the minimum value in arR. So an ordered loop array means that whatever is on the left of an ordered array goes to the right, and whatever is on the right goes to the left. For example, arrays 1,2,3,3,4 are ordered loops, as are arrays 4,1,2,3, and 3.
Enter the sample | The output sample |
---|---|
,1,2,3 0, 1, 1, 1 | 1 (res = 4) |
0 | 0 |
2,2,2,2,1,2,2,2 | 1 |
function Min(arr) {
// The res is just the index, you don't have to write it.
let res = -1;
if (arr.length === 0) {
return res // The array is empty. To find the failure
} else if (arr.length === 1 || arr[0] < arr[arr.length - 1]) {
// If the first value in the array is less than the last value, it has not been flipped
return arr[0]}else {
let left = 0,
right = arr.length - 1,
mid = 0
while (left <= right) {
mid = Math.trunc(left + (right - left) / 2)
if (left + 1 === right) {
res = arr[left] > arr[right] ? right : left
return arr[res]
} else {
if (arr[left] > arr[mid]) {
right = mid
} else if (arr[mid] > arr[right]) {
left = mid
} else if (arr[left] === arr[mid] && arr[mid] === arr[right]) {
let min = arr[0]
for (let i = 1; i < arr.length; i++) {
// This is in response to input sample 3, traversal search
if (arr[i] < arr[0]) {
res = i
return arr[res]
}
}
}
}
}
}
}
Copy the code
2
Same problem. What if you had to find the median?
function Min(arr) {
let res = "Array empty, no median";
let m = Math.trunc(arr.length/2)
var num = function(res){
if (arr.length % 2! = =0) {
res = arr[(res + m) % arr.length]
} else {
num1 = arr[(res + m) % arr.length]
num2 = arr[(res + m -1 ) % arr.length]
res = (num1 + num2) / 2
}
return res
}
if (arr.length === 0) {
return res // The array is empty. To find the failure
} else if (arr.length === 1) { // A value in the array
return arr[0]}else if(arr[0] < arr[arr.length - 1]) {// The first one is less than the last one
return num(0)}else {
let left = 0,
right = arr.length - 1,
mid = 0
while (left <= right) {
mid = Math.trunc(left + (right - left) / 2)
if (left + 1 === right) {
res = num(arr[left] > arr[right] ? right : left)
return res
} else {
if (arr[left] > arr[mid]) {
right = mid
} else if (arr[mid] > arr[right]) {
left = mid
} else if (arr[left] === arr[mid] && arr[mid] === arr[right]) {
let min = arr[0]
for (let i = 1; i < arr.length; i++) {
// This is in response to input sample 3, traversal search
if (arr[i] < arr[0]) {
res = num(a[i])
return arr[res]
}
}
}
}
}
}
}
Copy the code
Application: faster to find an integer k to the N power.
If the time complexity of multiplying two integers and getting the result is O(1), the process of getting the integer k to the N is k*k*… *k complexity is O(n), please find a way to implement the time complexity is O(logN) method.
This is also using the idea of binary search, although I didn’t see it. But I have to say that the algorithm is profound!!
function calculate(a, b) {
let arr = []
// Convert b to base 2 representation
while(b ! =0) {
arr.push(b % 2)
b = Math.trunc(b / 2)}console.log(arr)
let mul = a
let res
if(arr[0]! = =0){
res = a
}else{
res = 1
}
// How many bits do you have in b
for (let i = 1; i < arr.length; i++) {
mul *= mul
console.log("mul: "+mul)
if (arr[i] === 1) {
res *= mul
console.log(res)
}
}
}
Copy the code
The title comes from the interview algorithm.