Algorithm 查找不在列表中的最小非负整数的算法
给定一个整数列表,如何最好地找到不在列表中的整数 列表可能非常大,整数可能很大(即大整数,而不仅仅是32位整数) 如果有什么不同,列表是“可能”排序的,即99%的时间会被排序,但我不能依赖总是被排序 编辑-Algorithm 查找不在列表中的最小非负整数的算法,algorithm,sorting,integer,Algorithm,Sorting,Integer,给定一个整数列表,如何最好地找到不在列表中的整数 列表可能非常大,整数可能很大(即大整数,而不仅仅是32位整数) 如果有什么不同,列表是“可能”排序的,即99%的时间会被排序,但我不能依赖总是被排序 编辑- 为了澄清,鉴于列表{0,1,3,4,7},可接受解决方案的示例为-2,2,8和10012,但我更愿意找到最小的非负解决方案(即2)如果有一种算法可以找到它,而不需要对整个列表进行排序。除非对其进行排序,否则必须逐项进行线性搜索,直到找到匹配项或到达列表的末尾。如果您可以保证它是排序的,那么您
为了澄清,鉴于列表{0,1,3,4,7},可接受解决方案的示例为-2,2,8和10012,但我更愿意找到最小的非负解决方案(即2)如果有一种算法可以找到它,而不需要对整个列表进行排序。除非对其进行排序,否则必须逐项进行线性搜索,直到找到匹配项或到达列表的末尾。如果您可以保证它是排序的,那么您可以始终使用BinarySearch的数组方法,或者直接使用您自己的二进制搜索
或者像Jason提到的,总是可以选择使用哈希表。一个简单的方法是迭代列表以获得最高值
n
,然后您知道n+1
不在列表中
编辑:
找到最小未使用正数的方法是从零开始,扫描列表中的该数字,重新开始,如果找到该数字,则增加。为了提高效率,并利用列表被排序的高概率,可以将小于当前值的数字移动到列表中未使用的部分
此方法使用列表开头作为较低数字的存储空间,startIndex
变量跟踪相关数字的起始位置:
public static int GetSmallest(int[] items) {
int startIndex = 0;
int result = 0;
int i = 0;
while (i < items.Length) {
if (items[i] == result) {
result++;
i = startIndex;
} else {
if (items[i] < result) {
if (i != startIndex) {
int temp = items[startIndex];
items[startIndex] = items[i];
items[i] = temp;
}
startIndex++;
}
i++;
}
}
return result;
}
publicstaticintgetminimable(int[]项){
int startIndex=0;
int结果=0;
int i=0;
while(i
我做了一个性能测试,在那里我创建了10万个从0到19999的随机数的列表,这使得平均最低数在150左右。在测试运行中(每个测试列表有1000个),该方法在未排序列表中发现的最小数量平均为8.2毫秒,在排序列表中发现的最小数量平均为0.32毫秒
(我没有检查该方法离开列表的状态,因为它可能会交换列表中的某些项。它离开的列表至少包含相同的项,并且当它向下移动较小的值时,我认为它实际上应该在每次搜索时变得更排序。)除非您100%确定它已排序,最快的算法仍然必须至少查看列表中的每个数字一次,以至少验证列表中没有数字。“可能已排序”意味着您必须将其视为完全未排序。当然,如果你能保证它被分类,这很简单。只需查看第一个或最后一个元素并加或减1。理论上,找到最大值并加1。假设受BigInteger类型的最大值约束,如果未排序,则对列表进行排序,并查找间隙。如果数字没有任何限制,则可以执行线性搜索以查找列表中的最大值,并返回大一的数字 如果数字确实有限制(例如,max+1和min-1可能会溢出),则可以使用排序算法。然后浏览列表,找到第一对不连续的数字v_i和v_{i+1}。返回v_i+1 要获得最小的非负整数(基于问题中的编辑),您可以:
- 使用如上所述的部分排序对列表进行排序。二进制搜索列表中的0。从该值遍历列表,直到找到两个数字之间的“间隙”。如果到达列表的末尾,请返回最后一个值+1
- 将值插入哈希表。然后从0向上迭代,直到找到不在列表中的整数
- 找到列表中最大的整数并将其存储在x中。x+1将不在列表中。这同样适用于使用min()和x-1
- 当N是列表的大小时,分配一个大小为
的int数组。对于列表中的每个元素,在数组索引i/32处设置整数的位(N+31)/32
(其中v&31
是元素的值)。忽略v
的值。现在搜索第一个数组项,即“!=0xFFFFFF'(用于32位整数)i/32>=array.length
- 可以在O(N)内完成吗
- 什么是最佳空间效率 Chris Doggett的查找最大值并添加1的解决方案是O(N)和空间效率(O(1)内存使用)
- 您是否正在寻找一个(因为您说输入任意大)?如果是这样,请看一看
否则,如前所述,对布尔集合的输入、搜索和打开/关闭元素进行散列(将散列索引放入集合中)。有几种方法:
如果你只想要最好的答案,那么这是一个不同的问题。假设这就是我正在思考的问题: 在
1
到n
范围内,您有一个集合
所有整数
,但其中一个整数
丢失。告诉我缺少int
中的哪一个
这是一个很容易用一些简单的数学知识来解决的问题。众所周知
public int solution(int[] A) {
if (A != null && A.length > 0) {
quickSort(A, 0, A.length - 1);
}
int result = 1;
if (A.length == 1 && A[0] < 0) {
return result;
}
for (int i = 0; i < A.length; i++) {
if (A[i] <= 0) {
continue;
}
if (A[i] == result) {
result++;
} else if (A[i] < result) {
continue;
} else if (A[i] > result) {
return result;
}
}
return result;
}
private void quickSort(int[] numbers, int low, int high) {
int i = low, j = high;
int pivot = numbers[low + (high - low) / 2];
while (i <= j) {
while (numbers[i] < pivot) {
i++;
}
while (numbers[j] > pivot) {
j--;
}
if (i <= j) {
exchange(numbers, i, j);
i++;
j--;
}
}
// Recursion
if (low < j)
quickSort(numbers, low, j);
if (i < high)
quickSort(numbers, i, high);
}
private void exchange(int[] numbers, int i, int j) {
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
using System.Collections.Generic;
using System.Linq;
class Solution {
public int solution(int[] A) {
if (A == null) {
return 1;
} else {
if (A.Length == 0) {
return 1;
}
}
List<int> list_test = new List<int>(A);
list_test = list_test.Distinct().ToList();
list_test = list_test.Where(i => i > 0).ToList();
list_test.Sort();
if (list_test.Count == 0) {
return 1;
}
int lastValue = list_test[list_test.Count - 1];
if (lastValue <= 0) {
return 1;
}
int firstValue = list_test[0];
if (firstValue > 1) {
return 1;
}
return BinarySearchList(list_test);
}
int BinarySearchList(List<int> list) {
int returnable = 0;
int tempIndex;
int[] boundaries = new int[2] { 0, list.Count - 1 };
int testCounter = 0;
while (returnable == 0 && testCounter < 2000) {
tempIndex = (boundaries[0] + boundaries[1]) / 2;
if (tempIndex != boundaries[0]) {
if (list[tempIndex] > tempIndex + 1) {
boundaries[1] = tempIndex;
} else {
boundaries[0] = tempIndex;
}
} else {
if (list[tempIndex] > tempIndex + 1) {
returnable = tempIndex + 1;
} else {
returnable = tempIndex + 2;
}
}
testCounter++;
}
if (returnable == list[list.Count - 1]) {
returnable++;
}
return returnable;
}
}