《資料結構與演算法之美》專欄閱讀筆記4 二分查詢

2021-08-31 18:34:57 字數 3149 閱讀 5021

找呀找呀找朋友

1、二分查詢

二分查詢也叫折半查詢,是一種針對有序資料集合的查詢演算法。

原理:押大押小呀?

複雜度分析

2^k = n,o(logn)

適用場景

作業~【求乙個數的平方根,精確到小數點後6位】

看到題目的第一反應是,啥?啥叫平方根?精確到小數點後是幾個意思?小數點單獨算?(訊號處理專業中數學最差的說的大概就是我……)反應過來啥叫平方根後,腦補了一下小數點的限制的方法,然後就……想起來作者之前的忠告:

}強迫症般糾結的我發現36的平方根居然不是6的時候,面臨崩潰,才發現不是我的鍋。

科普一下牛頓-拉弗森法(喜歡講著麼清楚的文~)

用來求平方根的話,公式大概就是:

實現就是

public static double sqrt2(double value) 

return c;

}

36的平方根就是6了呢~

(還是學數學的厲害呢~)

2、變形的二分查詢

常見的四個變形問題

2.1、查詢第乙個、最後乙個值等於給定值的元素

下面是查詢第乙個等於給定值的元素的實現**。

原始寫法

public static int firstequal(int values, int target)  else 

mid = left + ((right - left) >> 1);

}while (mid >= 0 && values[mid] == target)

return mid+1;

}

跟作者給出來的說是不好理解的寫法差不多的呢,就是看到下面的while之後就發現我可能是瞬間腦抽了。不過看到「標準答案」後也明白了這樣好像更優雅,同時也說明我雖然「不小心」處理了等於的情況,但是沒有理解等於的情況交給右邊界其實可以保證左邊界收縮到第乙個值的位置。

int left = 0;

int right = values.length - 1;

int mid = left + ((right - left) >> 1);

while (left < right) else

mid = left + ((right - left) >> 1);

}if (left < values.length && values[left] == target)

return left;

return -1;

另外一種更好理解的寫法,其實是把等於的情況單獨拿出來顯式宣告。跟我最開始的寫法一樣,不過比我寫的好地方在於把這個從mid往前查詢的動作放在了二分的迴圈裡面。

int left = 0;

int right = values.length - 1;

int mid = left + ((right - left) >> 1);

while (left < right) else if (values[mid] > target) else

mid = left + ((right - left) >> 1);

}return -1;

查詢最後乙個值等於給定值的元素是類似的,明白等於的情況交給誰處理會出現什麼樣的結果,那就很好辦了,找最後乙個值就是把等於的情況交給左邊界來處理,往右壓縮,最後乙個值等於給定值的元素會被壓縮到右邊界。

public static int lastequal(int values, int target)  else 

mid = left + ((right - left) >> 1);

}if (right < values.length && values[right] == target)

return right;

return -1;

}

對應的,這樣更好理解呢~

int left = 0;

int right = values.length - 1;

int mid = left + ((right - left) >> 1);

while (left < right) else if (values[mid] > target) else

mid = left + ((right - left) >> 1);

}return -1;

2.2、查詢第乙個大於等於、最後乙個小於等於給定值的元素

找第乙個大於等於給定值 = 找乙個最小右邊界。

找最後乙個小於等於給定值 = 找乙個最大左邊界。

public static int lastmin(int values, int target)  else 

}return -1;

}public static int firstmax(int values, int target) else

}return -1;

}

2.3、思考題

在乙個迴圈有序陣列中查詢值等於給定值的情況,如在[4,5,6,1,2,3]中查詢2。

public static int findtargetincircle(int values, int target)  else if (values[mid] > target)  else 

} else else }}

return -1;

}

炫耀,leetcode上的第33題。

同理,對迴圈的陣列求上面四個二分的變形問題,只需要把values[mid] == target時的處理加到對應的位置即可~

資料結構與演算法之美專欄筆記 遞迴篇

假設a的推薦人是b,b的推薦人是c,如何來查詢a的最終推薦人呢?這裡直接給出答案 long findrootrerfererid long actorid 遞迴是一種應用非常廣泛的演算法,亦可稱作程式設計技巧。遞迴顧名思義,包含遞與歸兩個過程。我們用下面的例子來體會一下。假設你去電影院看電影,你想知...

資料結構與演算法之美

什麼是資料結構?什麼是演算法 狹義重點 複雜度分析 方法 邊學邊練,適度刷題 複雜度分析 時間複雜度 常見時間複雜度 非多項式量級 非常低效的演算法 空間複雜度 漸進空間複雜度,表示演算法的儲存空間和資料規模的增長關係 最好情況時間複雜度 理想情況的時間複雜度 最壞情況時間複雜度 最糟糕的情況下的時...

資料結構與演算法之美(筆記9)雜湊演算法

我們前面講到雜湊表,雜湊函式,這裡又是雜湊演算法,實際上,雜湊函式就是雜湊演算法的乙個特例。只不過在雜湊表中,我們通常希望雜湊函式簡單,才不會影響查詢等的效能。雜湊演算法的定義和原理很簡單,就是把任意二進位制串值對映為固定長度的二進位制值串,這個對映的規則就是雜湊演算法,而通過原始的資料對映之後得到...