题目描述:给定一个含n(n≥1)个整数的数组,请设计一个时间上尽可能高效的算法,找出数组中未出现的最小正整数。例如,数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}中未出现的最小正整数是4。
答案的方法是用空间换时间,时间复杂度O(n),空间复杂度O(n),答案很清晰,我是想记录一下自己的另一种思路。
#include
// 查找未出现的最小正整数的函数
int find(int a[],int n){
int k,i,c;
k = 1;
for(i=0;i<n;i++) {
if(a[i] == k){
++k;
i=0;// 其实每次找到后a[i]后,将i重置为0,也就相当于多了一层循环
}
}
return k;
}
int main() {
int a[100],i,n,res;
printf("请输入数组个数:");
scanf("%d",&n);
printf("请输入每个元素的值:\n");
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
res = find(a,n);
printf("最大正整数是: %d\n",res);
return 0;
}
#include
// 快速排序
void QuickSort(int arr[], int low, int high)
{
if (low < high)
{
int i = low;
int j = high;
int k = arr[low];
while (i < j)
{
while(i < j && arr[j] >= k) // 从右向左找第一个小于k的数
{
j--;
}
if(i < j)
{
arr[i++] = arr[j];
}
while(i < j && arr[i] < k) // 从左向右找第一个大于等于k的数
{
i++;
}
if(i < j)
{
arr[j--] = arr[i];
}
}
arr[i] = k;
// 递归调用
QuickSort(arr, low, i - 1); // 排序k左边
QuickSort(arr, i + 1, high); // 排序k右边
}
}
// 查找未出现的最小正整数的函数
int find(int a[],int n){
int k,i,c;
k = 1;
QuickSort(a, 0, n-1);
for(i=0;i<n;i++) {
if(a[i] == k){
k++;
} else {
break;
}
}
c = k;
return c;
}
int main() {
int a[100],i,n,res;
printf("请输入数组个数:");
scanf("%d",&n);
printf("请输入每个元素的值:\n");
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
res = find(a,n);
printf("最大正整数是: %d\n",res);
return 0;
}
其实可以看出,当数组是有序的时候,会使得题目简单很多,而时间复杂度也就是排序的时间复杂度。(包括写其他题目的时候也有这样的感觉)。大一学数据结构的时候不明白为什么排序那么重要,而现在明白了,不断地改进排序的算法,使得时间复杂度尽可能小是有它的道理的!