Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
