天天看點

找出奇數個數中唯一出現一次的數

問題描述

 現在有一堆奇數個數字,隻有一個出現了一次,其餘都出現了偶數次,找出這個數。

解決思路

 如果采用簡單周遊的方法統計每一個出現的次數,然後輸出次數為1的數,這樣有點複雜,時間複雜度為O(n2)。

#include<iostream>
using namespace std;
typedef struct {
    int value;
    int count=;
}Num;
int main() {
    int n;
    Num num[];
    int answer;
        cin >> n;
        while (n %  == ) {
            cout << "請輸入奇數:";
            cin >> n;
        }
        for (int i = ;i < n;i++) {
            int flag = ;
            cin >> num[i].value;
            for (int j = ;j < i;j++) {  //循環周遊以前的數
                if (num[j].value == num[i].value) {
                    flag = ;
                    num[j].count++;
                }
            }
            if (flag) {  //若存在相等,則本身也要count++;
                num[i].count++;
            }
        }
        for (int i = ;i < n;i++) {    //找出出現的一次的數
            if (num[i].count == ) {
                answer = num[i].value;
                break;
            }
        }
        cout << answer << endl;
}
           

 如何才能進一步降低時間複雜度呢,這裡用到位運算異或的方法,利用數的二進制位解決問題,相同的數字異或的結果是全0二進制數,微觀的說,所有偶數個的數的位的值出現偶數次,最後的異或的結果必為0,這樣出現一次的數就會使這些位數出現的次數為奇數,是以最後異或的結果就是我們要找的數,時間複雜度為O(1).

異或:1與1、0與0異或為0,而1與0異或為1。
#include<iostream>
using namespace std;
int solve(int num[],int n) {  //異或
    int answer=num[];
    for (int i = ;i < n;i++) {  //循環每次都與結果異或
        answer^=num[i];
    }
    return answer;
}
int main() {
    int n;
    cin >> n;
    int num[];
    while (n %  == ) {
        cout << "請輸入奇數:";
        cin >> n;
    }
    for (int i = ;i < n;i++) {
        cin >> num[i];
    }
    int answer = solve(num,n);
    cout << answer << endl;
    cin >> n;
}