未排序数组中的可被二分搜索的数
难度:
标签:
题目描述
代码结果
运行时间: 66 ms, 内存: 26.5 MB
/*
* LeetCode 1966: Find Elements in Unsorted Array that Can be Binary Searched
*
* 思路:
* 1. 使用Java Stream来解决这个问题。
* 2. 我们依然使用两个数组:leftMax和rightMin。
* 3. leftMax[i]表示从左到i的子数组中的最大值。
* 4. rightMin[i]表示从i到右的子数组中的最小值。
* 5. 对于每个元素,如果leftMax[i-1] <= nums[i] <= rightMin[i+1],那么它可以通过二分搜索找到。
*/
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Solution {
public List<Integer> binarySearchableNumbers(int[] nums) {
int n = nums.length;
int[] leftMax = new int[n];
int[] rightMin = new int[n];
leftMax[0] = nums[0];
for (int i = 1; i < n; i++) {
leftMax[i] = Math.max(leftMax[i-1], nums[i]);
}
rightMin[n-1] = nums[n-1];
for (int i = n-2; i >= 0; i--) {
rightMin[i] = Math.min(rightMin[i+1], nums[i]);
}
return IntStream.range(0, n)
.filter(i -> (i == 0 || nums[i] >= leftMax[i-1]) && (i == n-1 || nums[i] <= rightMin[i+1]))
.mapToObj(i -> nums[i])
.collect(Collectors.toList());
}
}
解释
方法:
该题解的核心思路是检查每个数组元素是否可以通过二分搜索确定其位置。一个元素x是可被二分搜索的,如果它的位置不受其左侧元素的最大值和右侧元素的最小值的影响。算法首先从左向右遍历数组,记录到目前为止的最大值,如果当前元素小于这个最大值,则其不可能是可被二分搜索的元素。接着,算法从右向左遍历数组,记录到目前为止的最小值,如果当前元素大于这个最小值,则其同样不可能是可被二分搜索的元素。最终,所有同时不被左侧最大值和右侧最小值影响的元素计数即为答案。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在算法中需要从两个方向遍历数组来判断一个元素是否可被二分搜索?
▷🦆
在从左向右遍历时,将最大值初始化为-1000000是否安全,或者这个值是否应该依赖于数组中的具体数据类型和范围?
▷🦆
在遍历数组的过程中,如果数组中存在重复元素,这种情况下算法的处理方式是怎样的,特别是对于那些重复元素?
▷🦆
算法返回的结果是可被二分搜索的元素数量,如果要修改算法使其直接返回这些元素的索引,应如何调整?
▷