一、實踐題目
改寫二分搜索算法
二、問題描述
設a[0:n-1]是已排好序的數組,請改寫二分搜索算法,使得當x不在數組中時,返回小於x的最大元素位置i和大於x的最小元素位置j。當搜索元素在數組中時,i和j相同,均為x在數組中的位置。
輸入格式:
輸入有兩行:
第一行是n值和x值; 第二行是n個不相同的整數組成的非降序序列,每個整數之間以空格分隔。
輸出格式:
輸出小於x的最大元素的最大下標i和大於x的最小元素的最小下標j。當搜索元素在數組中時,i和j相同。 提示:若x小於全部數值,則輸出:-1 0 若x大於全部數值,則輸出:n-1的值 n的值
輸入樣例:
在這里給出一組輸入。例如:
6 5 2 4 6 8 10 12
輸出樣例:
在這里給出相應的輸出。例如:
1 2
三、算法描述
我們原來的二分查找算法BiSearch(int array [ ], int n, int key)尋找的是在序列(array)中存在的某個數(key),為了達到這一目的,我們需要定義左右兩個指針(left和right),如果找不到,最后的指針將會是 left > right ,根據題目要求,實際就是在二分搜索的基礎上增加若尋找不到目標元素,返回 left 指針與 right 指針所指向的元素下標。要注意最后找不到時left指向的是大於查找目標key的最小下標。
綜上,在查找過程中,若查找到目標元素,則直接輸出兩次mid,結束查找,否則,則在查找完畢后,分別輸出right 與 left指針指向的下標
四、算法分析
時間復雜度:二分查找是將數組 array 從中間切成大致相等的兩部分,取 array[n/2] 與key做比較,如果 target=a[n/2] ,則找到 key 。因為每次規模都小一半,我們可以假設查找了 k 次,則 2^k = n,所以 k = log n,所以時間復雜度為O(log n)。
空間復雜度:本題采用的是非遞歸的做法,而且變量不會隨着 n 而變化,所以空間復雜度為O(1)。
五、心得體會
之前一直以為二分查找就十分簡單,后來才發現原來有這么多的變通,不過在理解好最高根本的二分思想之后,也就都迎刃而解了。在做這道題的過程一開始理所當然以為left就是小於key的最大元素下標,后來人肉cpu跑了一遍才發現並不是。所以對於一些不理解的算法,我認為自己跟着算法一步一步算一遍有助於更好地理解算法。