面试题:数组元素统计、合并两个有序数组
1、(乐视TV面试题)给定数组A,大小为n,数组元素为0到n-1的数字,不过有的数字出现了多次,有的数字没有出现。请给出算法和程序,统计哪些数字没有出现,哪些数字出现了多少次。能够在O(n)的时间复杂度,O(1)的空间复杂度要求下完成。
思路:
两次遍历,第一次采用A来计数,它的位置应该是A[i] % n,找到计数位置,然后加上n,即A[A[i]%n]+=n;
第二次遍历,用来统计次数,frequency = A[i]/n
代码:
#include <stdio.h>
void repetition(int *A, int n)
{
if(A==NULL || n<=0)
return ;
int i=0;
for(i=0; i<n; i++)
{
A[(A[i])%n]+= n;
}
for(i=0; i<n; i++)
{
printf("Element = %d, times = %d\n", i, A[i]/n);
}
}
void main()
{
int a[10];
int i;
for(i=0; i<10; i++)
a[i]= 9 ;
repetition(a, 10);
}
运行结果:
拓展:
给定数组A,大小为n,数组元素为1到n的数字,不过有的数字出现了多次,有的数字没有出现。请给出算法和程序,统计哪些数字没有出现,哪些数字出现了多少次。能够在O(n)的时间复杂度,O(1)的空间复杂度要求下完成。
思路:
两次遍历,第一次,先进行A[i]=A[i]-1操作,将他转换成和上面的问题一样的,再采用A来计数,它的位置应该是A[i] % n,找到计数位置,然后加上n,即A[A[i]%n]+=n;第二次遍历,用来统计次数,frequency = A[i]/n
代码:
#include <stdio.h>
void repetition(int *A, int n)
{
if(A==NULL || n<=0)
return ;
int i=0;
for(i=0; i<n; i++)
{
A[i]=A[i]-1; //
A[(A[i])%n]+=n;
}
for(i=0; i<n; i++)
{
//printf("Element = %d, times = %d\n", i, A[i]/n);
printf("Element = %d, times = %d\n", i+1, A[i]/n);
}
}
void main()
{
int a[10];
int i;
for(i=0; i<10; i++)
a[i]= 1 ;
repetition(a, 10);
}
运行结果:
2、数组al[0,mid-1] 和 al[mid,num-1],都分别有序。将其merge成有序数组al[0,num-1],要求空间复杂度O(1)
/*
*数组al[0,mid-1] 和 al[mid,num-1],都分别有序。将其merge成有序数组al[0,num-1],要求空间复杂度O(1)
*
*
*/
#include <stdio.h>
void merge(int *a, int mid, int n)
{
if(a==NULL || n<=0 || mid>n || mid<0)
{
return ;
}
int i = 0;
int j = mid;
int t = 0;
int index = 0;
while(i<n)
{
if(a[i]<a[j])
{
i++;
}
else //插入排序
{
t = a[j];
index = j;
for(; index>i; index--)
a[index] = a[index-1];
a[i] = t;
j++;
i++;
}
}
}
void main()
{
int a[10]={1, 5, 9, 10, 14, 2, 7, 8, 11, 20};
int mid = 5;
int n =10;
int i=0;
merge(a, mid, n);
for(i=0; i<n; i++)
printf("%d ", a[i]);
printf("\n");
}