Find bitonic point in given bitonic sequence in Python

A bitonic sequence is a sequence of numbers that first increases strictly, reaches a peak (the bitonic point), then decreases strictly. We need to find this peak element efficiently using binary search.

The bitonic point is the maximum element where the left neighbor is smaller and the right neighbor is also smaller.

Algorithm

We use binary search to find the bitonic point in O(log n) time ?

  • Compare the middle element with its neighbors
  • If array[mid-1] < array[mid] > array[mid+1], we found the bitonic point
  • If array[mid] < array[mid+1], the peak is in the right half
  • Otherwise, the peak is in the left half

Example

Let's implement the solution to find the bitonic point ?

def find_bitonic_point(array):
    left, right = 1, len(array) - 2
    
    while left <= right:
        mid = (left + right) // 2
        
        # Check if mid is the bitonic point
        if array[mid - 1] < array[mid] and array[mid] > array[mid + 1]:
            return mid
        
        # If increasing, peak is on the right
        elif array[mid] < array[mid + 1]:
            left = mid + 1
        
        # If decreasing, peak is on the left
        else:
            right = mid - 1
    
    return -1

# Test the function
array = [7, 8, 9, 12, 10, 6, 3, 2]
index = find_bitonic_point(array)

if index != -1:
    print(f"Bitonic point: {array[index]} at index {index}")
else:
    print("No bitonic point found")
Bitonic point: 12 at index 3

How It Works

For the array [7, 8, 9, 12, 10, 6, 3, 2] ?

def find_bitonic_point_verbose(array):
    left, right = 1, len(array) - 2
    
    while left <= right:
        mid = (left + right) // 2
        print(f"Checking index {mid}: {array[mid]}")
        print(f"Left: {array[mid-1]}, Mid: {array[mid]}, Right: {array[mid+1]}")
        
        if array[mid - 1] < array[mid] and array[mid] > array[mid + 1]:
            print(f"Found bitonic point at index {mid}")
            return mid
        elif array[mid] < array[mid + 1]:
            print("Moving right")
            left = mid + 1
        else:
            print("Moving left")
            right = mid - 1
        print()
    
    return -1

array = [7, 8, 9, 12, 10, 6, 3, 2]
find_bitonic_point_verbose(array)
Checking index 3: 12
Left: 9, Mid: 12, Right: 10
Found bitonic point at index 3

Edge Cases

The algorithm handles different bitonic sequences ?

def test_bitonic_sequences():
    sequences = [
        [1, 3, 8, 12, 4, 2],           # Standard bitonic
        [10, 20, 30, 40, 35, 25, 15], # Longer sequence
        [1, 2, 3, 4, 5],               # Only increasing (no bitonic point)
        [5, 4, 3, 2, 1]                # Only decreasing (no bitonic point)
    ]
    
    for i, seq in enumerate(sequences):
        print(f"Sequence {i+1}: {seq}")
        index = find_bitonic_point(seq)
        if index != -1:
            print(f"Bitonic point: {seq[index]} at index {index}")
        else:
            print("No bitonic point found")
        print()

test_bitonic_sequences()
Sequence 1: [1, 3, 8, 12, 4, 2]
Bitonic point: 12 at index 3

Sequence 2: [10, 20, 30, 40, 35, 25, 15]
Bitonic point: 40 at index 3

Sequence 3: [1, 2, 3, 4, 5]
No bitonic point found

Sequence 4: [5, 4, 3, 2, 1]
No bitonic point found

Time Complexity

The binary search approach gives us O(log n) time complexity, which is much better than the O(n) linear search approach.

Conclusion

Finding the bitonic point using binary search is efficient with O(log n) complexity. The algorithm compares middle elements with neighbors to determine the search direction, making it optimal for large bitonic sequences.

Updated on: 2026-03-25T09:14:32+05:30

703 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements