首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

經典面試題:從 1~n 中找出 3 個缺失數字的 O(n) 時間 O(n) 空間解法

     編輯:關於C語言

問題描述

有數組 A 長度 N-3,包含 1 到 N 中除 3 個缺失數字外的所有數,順序打亂。N=10000。要求快速找出 3 個缺失數。

核心思想:空間換時間 —— 標記陣列

利用數字範圍已知(1~N),建立大小 N+1 的輔助陣列 B,下標對應數字值,值為 0/1 標記是否出現。

演算法步驟

  1. 分配 int B[N+1] = {0};(索引 1~N 有效,0 忽略)。
  2. 遍歷 A,對每個 A[i] 置 B[A[i]] = 1。
  3. 再次遍歷 B[1...N],值為 0 的下標即為缺失數字。

代碼實現

void findMissing(int A[], int n_minus_3) {
    int N = n_minus_3 + 3;
    int *B = (int*)calloc(N + 1, sizeof(int)); // 自動歸零
    
    for (int i = 0; i < n_minus_3; i++) {
        if (A[i] >= 1 && A[i] <= N) B[A[i]] = 1;
    }
    
    printf("缺失的數字:");
    for (int i = 1; i <= N; i++) {
        if (B[i] == 0) printf("%d ", i);
    }
    printf("\n");
    free(B);
}

複雜度分析

  • 時間:O(N) 兩次線性掃描。
  • 空間:O(N) 輔助陣列(N=10000 约 40KB,極小)。

進階變體與優化方向

變體思路複雜度
只缺 1 個數求和公式 N*(N+1)/2 - sum(A)O(N) 時間,O(1) 空間
缺 2 個數建立 sum 和 sum_of_squares 方程組求解O(N) 時間,O(1) 空間
缺 k 個數 (k 固定小)位圖 或 k 次遍歷構造多項式O(N) 時間,O(N) 或 O(k) 空間
不可修改原數組、嚴格 O(1) 空間循環排序/置換法(將數字放到對應下標)O(N) 時間,O(1) 空間,但修改數組
數據流/超大 N布隆過濾器、MapReduce 分布式計數視具體架構

位圖優化(節省空間)

若 N 極大(如 1 億),int 陣列 400MB 過大。可用位圖:每個數佔 1 bit,N=1億 僅需 ~12.5MB。

// 位圖版
unsigned char *bitmap = calloc((N >> 3) + 1, 1);
#define SET_BIT(x)   (bitmap[(x)>>3] |=  (1 << ((x)&7)))
#define TEST_BIT(x)  (bitmap[(x)>>3] &   (1 << ((x)&7)))

for (int i=0; i

總結

「標記陣列 / 位圖」是解決**有限範圍整數集合差集**問題的通用利器:簡單、快速、易於並行化。面試中先給出 O(N) 空間解法,再根據面試官追問優化到 O(1) 空間(修改原數組)或位圖(巨大 N),展現完整工程思維。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved