java - 查找不存在的最佳搜索算法
问题描述
在数字范围内查找不存在数字的最佳搜索算法
我在数组上有以下数字范围: [3, -2, -1, 5, 6,7, -9 0, 1,2,3,5,7] 在开始时,我将数组更改为 Set 并使用过滤器只获取正数,我使用 stream().sorted() 按 asc 排序。
在结果列表中,我需要找到第一个不存在的数字。我实现了一个搜索线性算法,我检查下一个值位置减去当前位置值是否小于 2,如果为真,则当前位置值和下一个位置值之间不存在不存在的数字,如果为假,我返回这个数字不存在。
问题是不知道是否有更好的性能方法,但我知道线性算法的搜索成本最高。
我的代码
public static int nopresentnumber(int[] array) {
if (array == null)
return 1;
if (array.length == 0)
return 1;
final List<Integer> list =
Arrays.stream(array)
.boxed()
.filter(n -> n > 0)
.sorted()
.collect(Collectors.toSet())
.stream()
.collect(Collectors.toList());
final int listSize = list.size();
if (listSize == 0)
return 1;
final int min = list.get(0);
if (min > 1)
return 1;
for (int i = 0; i < listSize; i++) {
if (i < listSize - 1) {
final int x = list.get(i + 1) - list.get(i);
if (x > 1)
return list.get(i) + 1;
}
}
return list.get(listSize - 1) + 1;
}
在小范围内使用也不错。例如数组 [3, -2, -1, 5, 6,7, -9, 0, 1,2,3,5,7],答案是 4。但是如果范围很大并且有这么多的序列号算法太糟糕了。在示例橙色 [-100000... 到 -100000] 上,算法将检查 99999 次。
解决方案
[3, -2, -1, 5, 6,7, -9, 0, 1, 2, 3, 5, 7]
这个问题的答案似乎是-8
考虑到我们正在考虑负数并且我们正在寻找下一个连续缺失的数字。
我下面的解决方案考虑了负数,但如果你只想要正数,添加简单的if
检查应该不难。
片段:
import java.util.*;
class MyClass {
public static void main(String args[]) {
System.out.println(solve(new int[]{3, -2, -1, 5, 6,7, -9, 0, 1,2,3,5,7}));
}
private static int solve(int[] arr){
Set<Integer> set = new HashSet<>();
int minimum = arr[0];
for(int x : arr){
set.add(x);
if(minimum > x) minimum = x;
}
int find_missing_num = minimum - 1; // just to compare with a base value.
for(int x : arr){
if(!set.contains(x-1)){
if(find_missing_num == minimum - 1 && (x-1) != minimum - 1 || find_missing_num > x - 1) find_missing_num = x - 1;
}
if(!set.contains(x+1)){
if(find_missing_num == minimum - 1 && (x+1) != minimum - 1 || find_missing_num > x + 1) find_missing_num = x + 1;
}
}
return find_missing_num;
}
}
演示: https ://ideone.com/KPoiXR
算法:
- 首先创建一个
Set
并将所有数组值添加到集合中。 - 其次是再次遍历数组并检查是否
array_element - 1
存在array_element + 1
。 - 如果我们没有找到它们,我们会
find_missing_num
相应地更新我们的代码。 - 时间复杂度:O(n),空间复杂度:O(n) 其中
n
是数组的大小。
要找到第一个缺失的正数(同时忽略数组中的所有负数):
import java.util.*;
class MyClass {
public static void main(String args[]) {
//System.out.println(solve(new int[]{3, -2, -1, 5, 6,7, -9, 0, 1,2,3,5,7}));
System.out.println(solve(new int[]{-1,0,2,3}));
}
private static int solve(int[] arr){
Set<Integer> set = new HashSet<>();
int minimum = -1;
for(int x : arr){
if(x > -1){
set.add(x);
if(minimum > x) minimum = x;
}
}
if(!set.contains(1)) return 1;
int find_missing_num = - 1; // just to compare with a base value.
for(int x : arr){
if(x > -1){
if(x-1 > 0 && !set.contains(x-1)){
if(find_missing_num == -1 || find_missing_num > x - 1) find_missing_num = x - 1;
}
if(!set.contains(x+1)){
if(find_missing_num == -1 || find_missing_num > x + 1) find_missing_num = x + 1;
}
}
}
return find_missing_num;
}
}
推荐阅读
- c# - 对值的操作不起作用(操作>数组>控制)
- javascript - 如何在 JavaScript 中使用条件从 2 个数组创建新的 json 数组?
- go - 如何对支持多个版本的服务器的特定服务进行节俭调用
- c# - 如何更快地执行此 System.Linq 语句?
- node.js - 容器没有响应端口:8080 上的 HTTP ping,站点启动失败。Azure Linux 网络服务
- windows - 使用列表中的文件名多次复制文件的批处理脚本
- winapi - MFC (C++):如何按设计设置 ListBox 的宽度?
- google-analytics - 自定义报告维度钻取中的 Google Analytics(分析)数据丢失
- go - 在 Golang 中实现可跟踪并发的最佳方法
- javascript - 过滤器不像我在 js 中理想化的方式那样工作