更新:
public static void main(String[] args) {
int[] data = {21, 34, 12, 88, 54, 73, 99, 100};
List<Integer> dataList = Arrays.stream(data).boxed().collect(Collectors.toList());
System.out.println(searchRange(0, 2, 20, 50, data));
System.out.println(searchRange(2, 3, 20, 80, data));
System.out.println(searchRange(0, 2, 20, 22, data));
public static boolean searchRange(int from, int to, int min, int max, int[] data) {
data = Arrays.copyOfRange(data, from, to + 1);
Arrays.sort(data);
int index = findInBoundaries(data, min, max);
return index != -1;
}
static int findInBoundaries(int[] data, int min, int max) {
int start = 0;
int end = data.length - 1;
int ans = -1;
while (start <= end) {
int mid = (start + end) / 2;
if (data[mid] >= min && data[mid] <= max) {
ans = mid;
break;
}
else if (data[mid] <= max) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
return ans;
}
输出
true
false
true
这段代码已经进行了多次测试。与我第一个回答中独立命中最小值和最大值边界的方法不同,这个方法是通过确定目标元素的范围来判断子数组是否包含符合条件的数字。
解释:
为了简化问题,我将其定义为如果子数组中的任何数字在给定范围内,并且方法的时间复杂度应小于O(n^2)。
一旦数组排序完成,就可以使用二分搜索来解决。解决方案从中间元素开始(int mid = (start + end) / 2),在给定范围内搜索一个数字。当元素满足范围要求时,循环终止。如果它小于(或小于等于)最大值,则搜索右侧(较大)元素;否则,搜索左侧(较小)元素。在这种情况下,最大循环次数将为O(log n),其中n是数组的大小。
示例:
我修改了代码以通过添加计数器来比较解决方案与普通循环的效率。在某些情况下,普通循环需要遍历整个数组。
普通解决方案的排序并不是非常重要,所以我没有进行排序。
static void findBoundaryCompareMethods(int[] data, int min, int max) {
int start = 0;
int end = data.length - 1;
int ans = -1;
int count = 0;
while (start <= end) {
int mid = (start + end) / 2;
count++;
if (data[mid] >= min && data[mid] <= max) {
ans = mid;
break;
}
else if (data[mid] <= max) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
System.out.println("Method 1 Find: " + ans);
System.out.println("Method 1 Count: " + count);
ans = -1;
count = 0;
for (int i = 0; i < data.length; i++) {
count++;
if (data[i] >= min && data[i] <= max) {
ans = i;
break;
}
}
System.out.println("Method 2 Find: " + ans);
System.out.println("Method 2 Count: " + count);
}
测试输出如下。方法1是答案解决方案,方法2是正常解决方案。
输出
Array: [12, 21, 34]
Min: 20 Max: 50
Method 1 Find: 1
Method 1 Count: 1
Method 2 Find: 1
Method 2 Count: 2
Array: [12, 88]
Min: 20 Max: 80
Method 1 Find: -1
Method 1 Count: 2
Method 2 Find: -1
Method 2 Count: 2
Array: [12, 21, 34]
Min: 20 Max: 22
Method 1 Find: 1
Method 1 Count: 1
Method 2 Find: 1
Method 2 Count: 2
Array: [12, 21, 34, 54, 73, 88, 99, 100]
Min: 70 Max: 73
Method 1 Find: 4
Method 1 Count: 3
Method 2 Find: 4
Method 2 Count: 5
array[i]
的范围是什么? - Abhinav Mathurcheck(int a, int b, int l, int r)
,我将传入两个整数,a
表示左端点,b
表示右端点。 - lier wu