给出一个大小为n的数组。它包含1到n范围内的数字。每个号码都出现在 至少一次,除了2个号码。找到缺少的数字。 例如。一个5号的数组 元素是假设3,1,4,4,3
一种方法是
static int k;
for(i=1;i<=n;i++)
{
for(j=0;j<n;j++)
{
if(i==a[j])
break;
}
if(j==n)
{
k++;
printf("missing element is", a[j]);
}
if(k==2)
break;}
另一种解决方案可以.. 对于(I = 0;我
答案 0 :(得分:4)
首先让我解释概念:
你知道自然数的总和1 .... n是 (n *(n + 1))/ 2 。另外你知道前n个自然数的和的平方和1,2 .... n是 n *(n + 1)*(2n + 1)/ 6 。因此,您可以使用上述概念在O(n)时间内解决上述问题。
如果不考虑空间复杂性,您可以使用基于计数的方法,这需要O(n)时间和空间复杂度。
有关更详细的解决方案,请访问Find the two repeating elements in a given array
答案 1 :(得分:2)
我喜欢Algorithmist的link中的“使用数组元素作为索引”方法。
方法5(使用数组元素作为索引) 感谢Manish K. Aasawat建议这种方法。
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
唯一的区别是这里它将遍历1到n。
请注意,这是一个单程解决方案,不使用额外空间(除了存储i
)!
脚注:
技术上它“窃取”了一些额外的空间 - 本质上它是计数器阵列解决方案,但它不是分配自己的整数数组,而是使用原始数组的符号位作为计数器。
答案 2 :(得分:1)
我没有检查或运行此代码,但您应该明白这一点。
int print_missing(int *arr, size_t length) {
int *new_arr = calloc(sizeof(int) * length);
int i;
for(i = 0; i < length; i++) {
new_arr[arr[i]] = 1;
}
for(i = 0; i < length; i++) {
if(!new_arr[i]) {
printf("Number %i is missing\n", i);
}
}
free(new_arr);
return 0;
}
运行时应为O(2n)。如果我错了,请纠正我。
答案 3 :(得分:1)
使用qsort()
对数组进行排序,然后循环一次以查找缺失值。平均O(n * log(n))时间,因为排序和最小的常量额外存储。
答案 4 :(得分:0)
目前还不清楚为什么标记你看过的物品的天真方法(你可以使用比特场或数组)并不合适。 O(2n)CPU,O(n / 8)存储。
答案 5 :(得分:0)
如果您可以自由选择语言,请使用python的集合。
numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)
产生输出
set([2, 5])
答案 6 :(得分:0)
你走了。 C#解决方案:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
HashSet<int> values = new HashSet<int>( numbers ) ;
for( int value = 1 ; value <= numbers.Length ; ++value )
{
if ( !values.Contains(value) ) yield return value ;
}
}
答案 7 :(得分:0)
我发现您的代码存在许多问题。首先,j==n
将永远不会发生,并且这不会给我们丢失的号码。在尝试递增之前,还应将k
初始化为0。我写了一个类似于你的算法,但它可以正常工作。但是,它并不比你预期的更快:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n; j++)
{
if(a[j] == i)
{
found = true;
break;
}
}
if(!found)
{
printf("missing element is %d\n", i);
k++;
if(k==2)
break;
}
else
found = false;
}
H2H
答案 8 :(得分:0)
使用支持数组,您可以存档O(n)
int support[n];
// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
support[a[i]] += 1;
// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
if(support[i] == 0) printf("%d is missing", i);
答案 9 :(得分:0)
**
for(i=0; i < n;i++)
{
while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{
swap(a[i],a[a[i]-1]);
}
for(i=0;i< n;i++)
{
if(a[i]!=i+1)
printf("%d is missing",i+1); }
this takes o(n) time and o(1) space
======================================== **
答案 10 :(得分:0)
我们可以使用以下代码查找重复值和缺失值:
int size = 8;
int arr[] = {1, 2, 3, 5, 1, 3};
int result[] = new int[size];
for(int i =0; i < arr.length; i++)
{
if(result[arr[i]-1] == 1)
{
System.out.println("repeating: " + (arr[i]));
}
result[arr[i]-1]++;
}
for(int i =0; i < result.length; i++)
{
if(result[i] == 0)
{
System.out.println("missing: " + (i+1));
}
}
答案 11 :(得分:0)
这是一个采访问题:缺少数字。 条件1:数组不得包含任何重复项。 完整的解决方案是:
public class Solution5 {
public static void main(String[] args) {
int a[] = { 1,8,6,7,10};
Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
int ch = a[i];
if(start == ch) {
start++;
}else {
list.add(start);
start++;
//must do this
i--;
}
}//for
System.out.println(list);
}//main
}