Skip to content

Commit 0de1aa1

Browse files
committed
feat: add meta binary search algorithm
Fixes: #1835
1 parent 5c39e87 commit 0de1aa1

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

Search/MetaBinarySearch.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Meta Binary Search
3+
* https://www.geeksforgeeks.org/meta-binary-search-one-sided-binary-search/
4+
*
5+
* Builds the index bit by bit from the most-significant bit to the least-significant bit.
6+
* Works on sorted arrays and returns the index of target, or -1 if not found.
7+
*/
8+
9+
function metaBinarySearch(sortedArray, target) {
10+
if (!Array.isArray(sortedArray) || sortedArray.length === 0) {
11+
return -1
12+
}
13+
14+
const n = sortedArray.length
15+
const maxBit = Math.floor(Math.log2(n - 1 < 0 ? 0 : n - 1))
16+
17+
let position = 0
18+
for (let bit = maxBit; bit >= 0; bit--) {
19+
const candidate = position | (1 << bit)
20+
if (candidate < n && sortedArray[candidate] <= target) {
21+
position = candidate
22+
}
23+
}
24+
25+
return sortedArray[position] === target ? position : -1
26+
}
27+
28+
export { metaBinarySearch }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { metaBinarySearch } from '../MetaBinarySearch'
2+
3+
describe('Meta Binary Search', () => {
4+
test('returns index for found numeric element', () => {
5+
expect(metaBinarySearch([2, 5, 8, 12, 16, 23, 38], 23)).toBe(5)
6+
})
7+
8+
test('returns -1 when numeric element is missing', () => {
9+
expect(metaBinarySearch([2, 5, 8, 12, 16, 23, 38], 9)).toBe(-1)
10+
})
11+
12+
test('works with sorted strings', () => {
13+
expect(metaBinarySearch(['alpha', 'beta', 'delta', 'omega'], 'delta')).toBe(
14+
2
15+
)
16+
})
17+
18+
test('returns -1 on empty input', () => {
19+
expect(metaBinarySearch([], 1)).toBe(-1)
20+
})
21+
})

0 commit comments

Comments
 (0)