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

C語言位運算經典:找出陣列中唯一出現一次的數字 (XOR 消除法)

     編輯:關於C語言

C語言位運算經典:找出陣列中唯一出現一次的數字 (XOR 消除法)

**問題**:陣列中除一個數字出現一次外,其餘數字均出現**兩次**。找出該唯一數字。要求 O(n) 時間、O(1) 空間。

核心原理:XOR 性質

  • x ^ x = 0 (相同為 0)
  • x ^ 0 = x (與 0 異或不變)
  • x ^ y = y ^ x (交換律)
  • (x ^ y) ^ z = x ^ (y ^ z) (結合律)

成對出現的數字兩兩 XOR 抵消為 0,剩下的即為唯一數字。

完整程式碼

#include <stdio.h>

int find_single(int *arr, int len) {
    int result = 0;
    for (int i = 0; i < len; i++) {
        result ^= arr[i];
    }
    return result;
}

int main() {
    int arr[] = {1, 3, 3, 1, 4, 9, 4, 5, 5};
    int len = sizeof(arr) / sizeof(arr[0]);
    
    int single = find_single(arr, len);
    printf("唯一出現一次的數字:%d\n", single);  // 9
    
    return 0;
}

執行過程演示

初始:result = 0
0 ^ 1 = 1
1 ^ 3 = 2
2 ^ 3 = 1
1 ^ 1 = 0
0 ^ 4 = 4
4 ^ 9 = 13
13 ^ 4 = 9
9 ^ 5 = 12
12 ^ 5 = 9  ← 最終結果

執行結果

唯一出現一次的數字:9

進階變體與解法

變體條件解法複雜度
單一唯一,其餘出現 2 次本題XOR 全陣列O(n) / O(1)
單一唯一,其餘出現 3 次位計數法32 位計數器取模 3O(32n) / O(1)
兩個唯一,其餘出現 2 次分組 XOR找異或結果的任一 1 位分組O(n) / O(1)
單一出現 k 次,其餘 m 次通用位計數每位計數取模 mO(32n) / O(1)

變體二:其餘出現 3 次,位計數法實現

int find_single_3(int *arr, int len) {
    int count[32] = {0};
    for (int i = 0; i < len; i++) {
        for (int b = 0; b < 32; b++) {
            if (arr[i] & (1 << b)) count[b]++;
        }
    }
    int result = 0;
    for (int b = 0; b < 32; b++) {
        if (count[b] % 3) result |= (1 << b);
    }
    return result;
}

變體三:兩個唯一數字,分組 XOR

void find_two_single(int *arr, int len, int *a, int *b) {
    int xor_all = 0;
    for (int i = 0; i < len; i++) xor_all ^= arr[i];
    
    // 找到 xor_all 中任一為 1 的位 (lowbit)
    int diff_bit = xor_all & (-xor_all);
    
    *a = 0; *b = 0;
    for (int i = 0; i < len; i++) {
        if (arr[i] & diff_bit) *a ^= arr[i];
        else *b ^= arr[i];
    }
}

常見錯誤避坑

  1. 初始值不為 0:`result` 必須初始化為 0,否則結果錯誤。
  2. 陣列長度計算錯誤:函數參數傳遞陣列退化為指標,`sizeof(arr)` 失效,**必須傳遞長度**。
  3. 誤以為適用於「其餘出現 3 次」:XOR 僅適用於**偶數次**抵消,奇數次需位計數法。

總結

XOR 消除法是位運算最優雅的應用之一:**利用代數結構 (阿貝爾群) 的逆元特性**,將「查找唯一」轉化為「全局聚合」。掌握 XOR 三大性質 (自逆、單位元、交換結合律),即可秒殺單一/雙重/多重唯一數字變體。本題答案:**9**。

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