程式設計之美 第一章 1 5快速找出機器故障

2021-06-25 16:12:56 字數 1453 閱讀 8268

/*

快速找出機器故障:

為了保證搜尋引擎的服務質量,我們需要保證每份資料都有多個備份

假設乙個機器僅儲存了乙個標號為id的記錄(假設id是小於10億的整數),假設每份資料儲存了兩個備份,這樣

就有兩個機器儲存了同樣的資料。

1在某個時間,如果得到乙個資料檔案id的列表,是否能夠快速地找出這個表中僅出現一次的id?

2如果已經知道只有一台機器宕機(也就是說只有乙個備份都是)呢?如果有兩台機器宕機呢(假設同乙個資料

的兩個備份不會同時丟失)?

3如果丟失的兩台機器id相同呢?

分析:這個問題可以轉化成:有很多的id,其中只有乙個id出現的次數小於2,其他正常id出現的次數都等於2,如何找到

這個次數為1的id。

這樣就轉化成劍指上面的:所有元素全部異或,最終剩下的數就是那個數

第二問轉化為這群數中有兩個數各出現一次,其餘出現0次,所以也是劍指上的題目,需要全部異或得到數字

x,然後獲取x的位元表示中最右邊的1,記為該位為第n位,根據位元表示中的第n位是否為1,將陣列劃分

成兩部分,每一部分中在分別全部異或一遍,即可。

侷限:只能解決兩台故障機器id不同的情況。如果id相同,則無法解決

第三問:

預先計算並儲存好所有id的求和(不變數),順序列舉當前所有剩下的id,對它們求和,然後用總值 - 剩餘值 = 宕機

的機器id值。由於總和可以先計算好,演算法的時間複雜度為o(n),空間複雜度為o(1)

當兩個id不同時:總和 - 剩餘和 = x + y

當兩個id相同時:這個時候,x = (總和-剩餘和)/2

這個時候可以構造二元一次方程組來做,比如:總乘積/剩餘乘積 = x*y(或者求出x*x + y*y = b)

聯立解方程

int iremainarr[maxsize];

long long lremainsum = 0,lremainmul = 1,lintactsum = 0,lintactmul = 1;

for(int i = 0 ; i < n ; i++)

int iintactarr[maxsize];

for(int j = 0 ; j < n + 2 ; j++)

long long lsum = lintactsum - lremainsum;

long long lmul = lintactmul/lremainmul;

long long lsqrt = (long long)sqrt(double(lsum*lsum - 4*lmul) + 0.5);

long long lx = (long long)((lsum - lsqrt)/2);

long long ly = (long long)((lsum + lsqrt)/2);

printf("%lld %lld\n",lx,ly); }}

int main(int argc,char* argv)

程式設計之美 1 5 快速找出故障機器

解法3 使用異或 問題1 找出出現奇數次的兩個數 void findrepeatedtwonumbers int a,int n,int no1,int no2 temp的值現為兩個出現奇數次的數的異或 找第乙個為1的位 for j 0 j sizeof int 8 j 第j位為1,說明這兩個數字在...

程式設計之美 1 5 快速找出故障機器

題目 假設乙個機器只儲存乙個標號為id的記錄,假設每份資料儲存2個備份,這樣就有2個機器儲存了相同的資料。其中id是小於10億的整數 問題1 在某個時間,如果得到乙個資料檔案id的列表。是否能夠快速的找到這個表中僅出現一次的id?即快速找出出現故障的機器儲存的資料id。問題2 如果有兩台機器宕機呢?...

程式設計之美1 5 快速找出故障機器

題目 假設乙個機器只儲存乙個標號為 id的記錄,假設每份資料儲存 2個備份,這樣就有 2個機器儲存了相同的資料。其中id是小於10億的整數 問題1 在某個時間,如果得到乙個資料檔案 id的列表。是否能夠快速的找到這個表中僅出現一次的 id?即快速找出出現故障的機器儲存的資料id。問題2 如果有兩台機...