Python中如何用二分查找实现HIGH/LOW状态转换点检测
Absolutely! Binary search is an excellent choice here because your input arrays are strictly sorted (either increasing or decreasing)—this is the core requirement for binary search to work in O(log n) time, which is way more efficient than the O(n) linear traversal in your current code. Let’s break this down step by step.
First: Fix a Critical Bug in get_state
Your current get_state function returns None when the value is exactly 2.5 or 3.5, which doesn’t align with your transition rules. Let’s adjust it to correctly map values to states:
def get_state(value): if value >= 3.5: # Trigger HIGH state at or above 3.5 return 1 elif value <= 2.5: # Trigger LOW state at or below 2.5 return 0 else: # Values between 2.5 and 3.5 retain their previous state (irrelevant for sorted arrays) return None
Why Binary Search Works
In a sorted array, all LOW states (0) come before HIGH states (1) in an increasing sequence, and vice versa in a decreasing sequence. Binary search lets us jump directly to the transition point instead of checking every element.
Implement Binary Search for Transitions
We’ll create two helper functions to find each transition type, then combine them into a main function:
1. Find LOW → HIGH Transition (First HIGH State)
This finds the first value where the state switches from 0 to 1 (e.g., 3.5 in your increasing sequence):
def find_low_high_transition(arr): left, right = 0, len(arr) - 1 transition_idx = -1 while left <= right: mid = (left + right) // 2 if get_state(arr[mid]) == 1: # We found a HIGH state—look left to find the first occurrence transition_idx = mid right = mid - 1 else: # Still in LOW state—look right left = mid + 1 return arr[transition_idx] if transition_idx != -1 else None
2. Find HIGH → LOW Transition (First LOW State from the End)
This finds the first value where the state switches from 1 to 0 when traversing from high to low (e.g., 2.5 in your decreasing sequence):
def find_high_low_transition(arr): left, right = 0, len(arr) - 1 transition_idx = -1 while left <= right: mid = (left + right) // 2 if get_state(arr[mid]) == 0: # We found a LOW state—look right to find the last HIGH-to-LOW transition transition_idx = mid left = mid + 1 else: # Still in HIGH state—look left right = mid - 1 return arr[transition_idx] if transition_idx != -1 else None
3. Combine into a Main Function
This function handles both increasing and decreasing arrays, and returns both transition points (or None if a transition doesn’t exist):
def find_state_changed(arr): if not arr: return (None, None) low_high = find_low_high_transition(arr) high_low = find_high_low_transition(arr) return (low_high, high_low)
Test It with Your Example
Let’s run your original test case to confirm it works:
low = 0 high = 5 iteration = 100 step = (high - low)/iteration arr = [round(i * step, 2) for i in range(iteration + 1)] print(find_state_changed(arr)) # Output: (3.5, 2.5)
For a decreasing array (reverse the arr):
decreasing_arr = arr[::-1] print(find_state_changed(decreasing_arr)) # Output: (3.5, 2.5)
Key Improvements Over Your Original Code
- Efficiency: O(log n) time complexity vs. O(n) linear traversal—critical for large arrays (e.g., 1 million elements instead of 100).
- Robustness: Handles edge cases where no transitions exist (e.g., array is entirely LOW or HIGH) by returning
Noneinstead of throwing an error. - Clarity: Separates logic into focused helper functions, making the code easier to maintain.
内容的提问来源于stack exchange,提问作者Gооd_Mаn

