Tìm số nguyên dương nhỏ nhất không có trong mảng

Đề bài : Cho mảng a gồm n phần tử gồm cả số 0. Nhiệm vụ của bạn là tìm số nguyên dương nhỏ nhất không có mặt trong mảng
Ý tưởng: 1.Sắp xếp lại mảng
2. for từ 1 đến n+1
2.1 Nếu max của mảng nhỏ hơn 0 output 1
2.2 Nếu min của mảng lớn hơn 1 output 1
2.3 trường hợp còn lại thì nếu a[i] +1 !=a[i+1] thì output ra a[i]+1; break;
Ý tưởng trên chỉ đúng trong 1 số trường hợp ví dụ như ={ 1,2,3,4,5} output =6 nhưng trường hợp { -2 -1 -3 2 } thì output =3
Mọi người cho em xin ý kiến với ạ

Hai bước này nên đưa lên đầu. Mảng chỉ là không giảm thôi nên bước 2.3 sẽ bị sót.

3 Likes

vậy có thuật toán gì để hoàn thiện được các trường hợp còn lại không ạ

B1: sắp xếp tăng dần
B2. Bạn thử code này coi

code
if (a[0] > 1 || a[n-1] < 0){
  return result = 1;
}
for (i = 1; i < n - 1; i++){
   if (a[i] <= 0 && a[i+1] <= 0) {
       continue;
   }
   if (a[i] >= 0 && a[i] + 1 < a[i + 1]) {
     return result = a[i] + 1;
   }
}
return result = (a[i] + 1);
2 Likes

Bạn sort mảng rồi dùng hàm này, mình viết hàm này dựa trên ý tưởng của bạn ở trên và có cải tiến về hiệu suất một chút:

	if (0 == n) {
		return -1;
	}

	if (a[0] > 1 || a[n - 1] <= 0) {
		return 1;
	}
	
	//Giảm n đi 1, để điều kiện các vòng lặp bên dưới từ i < n - 1 trở thành i < n (tiết kiệm thời gian)
	--n;
	
	size_t i;
	
	//Hai dòng code sau là để làm cho mảng lúc nào cũng có số nguyên dương
	//Từ đó điều kiện của vòng for ở bên dưới từ a[i] < 0 && i < n - 1 trở thành a[i] < 0 (tiết kiệm thời gian)
	//Biến value_its để tránh mất giá trị của a[n - 1]
	int value_its = a[n]; //value_its = a[n - 1], do đã giảm n ở trên
	a[n] = 1; //Cho a[n - 1] = một số nguyên dương bất kì
	 
	//Chạy đến khi gặp số nguyên dương
	for (i = 0; a[i] <= 0; ++i);	
	
	//Sau khi duyệt xong thì trả lại giá trị cho a[n - 1]
	a[n] = value_its;
	
	//Nếu số nguyên dương đầu tiên của mảng > 1, thì số nguyên dương nhỏ nhất không xuất hiện trong mảng là 1
	if (a[i] > 1) {
		return 1;
	}
	
	for (; i < n; ++i) {
		//Nếu a[i + 1] - a[i] > 1, thì hai số này không phải là số liền kề, suy ra giữa chúng có một hoặc nhiều số nguyên khác
		//Vậy số cần tìm là a[i] + 1
		if (a[i + 1] - a[i] > 1) {
			return a[i] + 1;
		}
	}
	
	return a[i] + 1; //a[n - 1] + 1
}
3 Likes

sao hơi cực nhỉ, ý tưởng của mình là làm 1 mảng để đánh dấu các phần tử 0 đến n - 1 nằm trong mảng a, rồi tìm phần tử đầu tiên thuộc 0 … n - 1 mà không nằm trong a thôi.

mình viết tạm code kiểu như này nhé, chứ mấy năm rồi k code nó, chắc k chạy đc :smile:

int min_num(int a[], int n) {
  bool c[n] = {0};
  for (int i = 0; i < n; i++) {
    if (a[i] >= 0 && a[i] < n) {
      c[a[i]] = true;
    }
  }

  for (int i = 0; i < n; i++) {
    if (!c[i]) {
      return i;
    }
  }
  
  return 0;
}
3 Likes

cho 1 vòng for chạy từ 0 đến vô cùng
trong vòng for đấy chạy thêm vòng for nữa duyệt mảng
nếu có p tử ở vòng for trên khác với phẩn tử ở vòng for dưới(trong mảng) break rồi in luôn

đấy là mình nghĩ thế chứ chưa thử

1 Like
#include"stdio.h"
int main()
{
	int i,n,t=0,a[100],j;
	printf("nhap n \n");scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		printf("a[%d]=",i);scanf("%d",&a[i]);
	}
	printf("mdso vua nhap\n");
	for(i=1;i<=n;i++)
		printf("%5d",a[i]);
	// ham duyet mang,tim phan tu khac mang nho nhat
	
	for(j=0;;j++){
		if(t==1) break;
		for(i=1;i<=n;i++)
			{if(a[i]>=0){
				if(a[i]!=j) {
					t=1;printf("\n%d",j);break;
					}
				}		
			}
}
}
1 Like

code của bạn với trường hợp -1 -2 -3 4 thì sẽ sai mất

2 Likes
Đã edit
if (a[0] > 1 || a[n-1] < 0){
  return result = 1;
}
for (i = 1; i < n - 1; i++){
   if (a[i] <= 0){
     if (a[i+1] <= 1) {
       continue;
     }
     else {
       return result = 1;
     }
   }
   else (a[i] + 1 < a[i + 1]) {
     return result = a[i] + 1;
   }
}
return result = (a[i] + 1);
1 Like

Bạn thử làm vầy xem có nhanh hơn k?
Tạo ra mảng b chứa toàn bộ phần tử dương của mảng a (nguyên bản)

int j = -1;
for (int i = 0; i< n; i++){
	if(a[i] > 0){
		j++;
		b[j] = a[i];
	}
}
// Khong co a[i] > 0
if (j < 0){
	return result = 1;
}
//Sắp xếp mảng b tăng dần
//Duyệt để tìm result trên mảng b thôi
1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?