二分查找可定位元素问题:代码错误与TLE问题排查求助
问题分析与解决方案
首先明确核心判定逻辑:一个元素能被任意二分查找路径定位到,当且仅当:
- 该元素左侧所有元素都比它小
- 该元素右侧所有元素都比它大
道理很直白:如果左侧存在比它大的元素,某次二分选这个大元素当pivot时,会错误排除掉该元素所在的区间;右侧有更小元素的情况同理。
1. 修复binarySearchable函数的错误
如果你的binarySearchable是通过模拟各种二分路径来判断,这种思路不仅效率低,还容易漏判。直接用上面的核心条件判断才是正确的方式:
def is_binary_searchable(arr, idx): x = arr[idx] # 检查左侧所有元素都小于x for i in range(idx): if arr[i] > x: return False # 检查右侧所有元素都大于x for i in range(idx+1, len(arr)): if arr[i] < x: return False return True
但注意这个实现是每个元素O(n),整体O(n²),还是会超时,得进一步优化。
2. 解决超时问题(从O(n²)降到O(n))
通过预处理两个辅助数组,避免重复计算左右的最值:
prefix_max:prefix_max[i]记录arr[0..i]里的最大值suffix_min:suffix_min[i]记录arr[i..n-1]里的最小值
预处理完之后,每个元素只需做两次比较就能判断是否符合条件:
def how_many_binary_searchable(arr): n = len(arr) if n == 0: return 0 # 预处理前缀最大值数组 prefix_max = [0]*n prefix_max[0] = arr[0] for i in range(1, n): prefix_max[i] = max(prefix_max[i-1], arr[i]) # 预处理后缀最小值数组 suffix_min = [0]*n suffix_min[-1] = arr[-1] for i in range(n-2, -1, -1): suffix_min[i] = min(suffix_min[i+1], arr[i]) count = 0 for i in range(n): # 元素等于前缀最大值说明左侧都比它小,等于后缀最小值说明右侧都比它大 if arr[i] == prefix_max[i] and arr[i] == suffix_min[i]: count += 1 return count
这个实现时间复杂度O(n),空间复杂度O(n),完全不会触发TLE。
原代码超时的原因
- 你原来的
getBinarySearchableNumbers和howMany用了O(n²)的暴力检查,面对大数组(比如n=1e5)时,1e10次操作肯定超时。 - 模拟二分路径的思路(比如
binarySearchable尝试不同pivot)复杂度更高,还容易因为逻辑漏洞出现判断错误,比如没覆盖所有可能的pivot选择。
示例验证
- 输入
3,数组[3,2,1]:- prefix_max = [3,3,3],suffix_min = [1,1,1]
- 没有元素同时满足等于对应位置的前缀最大值和后缀最小值,输出0,符合示例。
- 输入
6,数组[3,2,5,4,6,7]:- prefix_max = [3,3,5,5,6,7],suffix_min = [2,2,4,4,6,7]
- 只有索引4的
6和索引5的7满足条件,输出2,符合示例。
内容的提问来源于stack exchange,提问作者Lalit LP
相关产品推荐
相关产品推荐

