diff --git a/DIRECTORY.md b/DIRECTORY.md index b7b8aca45d..b3511a1372 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -314,6 +314,7 @@ * [InterpolationSearch](Search/InterpolationSearch.js) * [JumpSearch](Search/JumpSearch.js) * [LinearSearch](Search/LinearSearch.js) + * [MetaBinarySearch](Search/MetaBinarySearch.js) * [Minesweeper](Search/Minesweeper.js) * [QuickSelectSearch](Search/QuickSelectSearch.js) * [RabinKarp](Search/RabinKarp.js) @@ -322,8 +323,8 @@ * [TernarySearch](Search/TernarySearch.js) * [UnionFind](Search/UnionFind.js) * **Sliding-Windows** - * [MaxSumSubarrayFixed](Sliding-Windows/MaxSumSubarrayFixed.js) * [LongestSubarrayWithSumAtMost](Sliding-Windows/LongestSubarrayWithSumAtMost.js) + * [MaxSumSubarrayFixed](Sliding-Windows/MaxSumSubarrayFixed.js) * **Sorts** * [AlphaNumericalSort](Sorts/AlphaNumericalSort.js) * [BeadSort](Sorts/BeadSort.js) diff --git a/Search/MetaBinarySearch.js b/Search/MetaBinarySearch.js new file mode 100644 index 0000000000..c2ef924516 --- /dev/null +++ b/Search/MetaBinarySearch.js @@ -0,0 +1,28 @@ +/** + * Meta Binary Search + * https://www.geeksforgeeks.org/meta-binary-search-one-sided-binary-search/ + * + * Builds the index bit by bit from the most-significant bit to the least-significant bit. + * Works on sorted arrays and returns the index of target, or -1 if not found. + */ + +function metaBinarySearch(sortedArray, target) { + if (!Array.isArray(sortedArray) || sortedArray.length === 0) { + return -1 + } + + const n = sortedArray.length + const maxBit = Math.floor(Math.log2(Math.max(1, n - 1))) + + let position = 0 + for (let bit = maxBit; bit >= 0; bit--) { + const candidate = position + 2 ** bit + if (candidate < n && sortedArray[candidate] <= target) { + position = candidate + } + } + + return sortedArray[position] === target ? position : -1 +} + +export { metaBinarySearch } diff --git a/Search/test/MetaBinarySearch.test.js b/Search/test/MetaBinarySearch.test.js new file mode 100644 index 0000000000..32607e6067 --- /dev/null +++ b/Search/test/MetaBinarySearch.test.js @@ -0,0 +1,28 @@ +import { metaBinarySearch } from '../MetaBinarySearch' + +describe('Meta Binary Search', () => { + test('returns index for found numeric element', () => { + expect(metaBinarySearch([2, 5, 8, 12, 16, 23, 38], 23)).toBe(5) + }) + + test('returns -1 when numeric element is missing', () => { + expect(metaBinarySearch([2, 5, 8, 12, 16, 23, 38], 9)).toBe(-1) + }) + + test('works with sorted strings', () => { + expect(metaBinarySearch(['alpha', 'beta', 'delta', 'omega'], 'delta')).toBe( + 2 + ) + }) + + test('returns index for a matching element in a single-element array', () => { + expect(metaBinarySearch([7], 7)).toBe(0) + }) + test('returns -1 on empty input', () => { + expect(metaBinarySearch([], 1)).toBe(-1) + }) + + test('returns index for a matching element in a single-element array', () => { + expect(metaBinarySearch([7], 7)).toBe(0) + }) +})