二分查詢問題全集OK

2021-06-18 04:36:43 字數 4585 閱讀 2433

題目:給定乙個有序(非降序)陣列a,求任意乙個i使得a[i]等於target,不存在則返回-1

例如:[2,4,6,8,9]找(4) 位置1

int bsearch(int a, int low, int high, int target)

int search(int a, int n, int target)

return -1;

}

給定乙個有序(非降序)陣列a,若target在陣列中出現,返回位置,若不存在,返回它應該插入的位置。

int search(int a, int n, int target)

return -(low+1);

}

之所以返回-(low+1)而不是直接返回-low是因為low可能為0,如果直接返回-low就無法判斷是正常返回位置0還是查詢不成功返回的0。

問題:給定乙個有序(非降序)陣列a,可含有重複元素,求最小的i使得a[i]等於target,不存在則返回-1

例如:a[2,4,6,8,8,8,9]求8得最小位置3

int search(int a, int n, int target)

else if(a[mid] < target)

low = mid+1;

else // a[mid] > target

high = mid-1;

} return -(low+1);

}

問題:給定乙個有序(非降序)陣列a,可含有重複元素,求最大的i使得a[i]等於target,不存在則返回-1

例如:a[2,4,6,8,8,8,9]求8得最大位置5

int search(int a, int n, int target)

else if(a[mid] < target)

low = mid+1;

else // a[mid] > target

high = mid-1;

} return -(low+1);

}

問題:給定乙個有序(非降序)陣列a,可含有重複元素,求最大的i使得a[i]小於target,不存在則返回-1

例如:a[2,4,6,8,8,8,9]求9得最大位置5

問題轉化:含重複元素,求2【=target的最小乙個】的前乙個。

int search(int a, int n, int target)

else if(a[mid] < target)

low = mid+1;

else // a[mid] > target

high = mid-1;

} return -(low+1);

}

問題:給定乙個有序(非降序)陣列a,可含有重複元素,求最小的i使得a[i]大於target,不存在則返回-1

例如:a[2,4,6,8,8,8,9]求6的最小位置3

問題轉化:含重複元素,求3【=target的最大乙個】的後乙個。

int search(int a, int n, int target)

else if(a[mid] < target)

low = mid+1;

else // a[mid] > target

high = mid-1;

} return -(low+1);

}

問題:給定乙個有序(非降序)陣列a,可含有重複元素,求target在陣列中出現的次數。

例如:a[2,4,6,8,8,8,9]求8的出現次數3

求出第一次出現位置和最後一次出現位置。由於前面都已實現,這裡不多解釋。請參考實現**與注釋

int count(int a, int n, int target)

問題:給定乙個有序(非降序)陣列a,可含有重複元素,求絕對值最小的元素的位置

例如:a[-4,-2,-1,2,3,8,9]求結果為2

int searchminabs(int a, int n)

/* 迴圈結束時,如果low != n-1,a[low] >= 0,如果low>0,a[low-1] < 0 */

if(low > 0 && abs(a[low-1]) < abs(a[low]))

return low-1;

else

return low;

}

8,問題:給定乙個有序(非降序)陣列a和乙個有序(非降序)陣列b,可含有重複元素,求兩個陣列合併結果中的第k(k>=0)個數字。

這個題目出現了兩個陣列,有序的,不管怎樣我們就應該首先考慮二分查詢是否可行。若使用順序查詢,時間複雜度最低為o(k),就是類似歸併排序中的歸併過程。使用用二分查詢時間複雜度為o(logm+logn)。二分查詢的具體實現過程請參考實現**與注釋。

int findkthin2sortedarrays(int a, int m, int b, int n, int k)

} /*

設y為陣列a和陣列b中小於於等於a[i]的元素數目,則i+1+j+1大於等於y;

如果k大於等於i+1+j+1,那麼要查詢到第k個元素肯定大於a[i],因為

i+1+j+1大於等於y;既然第k個元素大於a[i],那麼只需要在a[i+1]~a[m-1]

和b[0]~b[n-1]中查詢第k-i-1個元素,遞迴呼叫下去。

*/else

return findkthin2sortedarrays(a+i+1, m-i-1, b, n, k-i-1);

} // 如果陣列a的中間元素大於陣列b的中間元素,那麼交換陣列a和b,重新呼叫即可

else

return findkthin2sortedarrays(b, n, a, m, k);

}

9

問題:

乙個有序(公升序)陣列,沒有重複元素,在某乙個位置發生了旋轉後,求target在變化後的陣列中出現的位置,不存在則返回-1

如 0 1 2 4 5 6 7 可能變成 4 5 6 7 0 1 2

我們先比較中間元素是否是目標值,如果是返回位置。如果不是,我們就應該想辦法將搜尋區間減少一半。因為存在旋轉變化,所以我們要多做一些判斷。我們知道因為只有一次旋轉變化,所以中間元素兩邊的子陣列肯定有乙個是有序的,那麼我們可以判斷target是不是在這個有序的子陣列中,從而決定是搜尋這個子陣列還是搜尋另乙個子陣列。具體請參考實現**與注釋。

int searchinrotatedarray(int a, int n, int target) 

else

}return -1;

}

如果這樣的陣列中存在重複元素,還能使用二分嗎?答案是不能。請看幾個例子

[1, 2, 2, 2, 2], [2, 1, 2, 2, 2], [2, 2, 1, 2, 2], [2, 2, 2, 1, 2], [2, 2, 2, 2, 1]這些都是有第乙個陣列旋轉一次變化來的,我們不能通過二分確定是否存在元素1.

10,問題:乙個有序(公升序)陣列,沒有重複元素,在某乙個位置發生了旋轉後,求最小值所在位置

如果中間元素小於左端元素,則最小值在左半區間內(包含中間元素);如果中間元素大於右端元素,則最小值在右半區間內(包含中間元素)。請參考實現**與注釋。

int searchmininrotatedarray(int a, int n) 

return a[low] < a[low+1] ? low : low+1;

}

11,問題:

乙個有序(公升序)陣列,沒有重複元素,在某乙個位置發生了旋轉後,求第k(k > 0)小元素的位置

int searchkthinrotatedarray(int a, int n, int k) 

題目:即找分界點,比如3 4 5 1 2,返回的是位置3。

以題目中的旋轉陣列為例,,我們可以有序陣列經過旋轉以後被分割為兩段有序的陣列,比如此處被分為這樣連個陣列,並且前半段陣列中的數字肯定大於等於後半段的陣列。我們找中間元素a[mid],讓其跟元素首元素a[low]和尾元素a[high]比較,如果大於首元素a[low],則中間元素屬於前半段有序陣列;如果小於尾元素a[high],那麼中間元素就是後半段的元素。

這裡我們設定兩個指標start和end分別指向陣列的首尾元素,然後當start指向前半段最後乙個元素,end指向後半段第乙個元素,這是程式就找到了陣列中的最小元素,就是end指向的那個數,程式的出口就是 end-start==1。

int bsearchminvalue(int a, int low, int high)

return -1;

}

LeetCode二分查詢問題全集

int binarysearch int nums,int target else if nums mid target else if nums mid target return.分析二分查詢的乙個技巧是 不要出現 else,而是把所有情況用 else if 寫清楚,這樣可以清楚地展現所有細節 ...

查詢問題 二分查詢

首先,查詢的方式有很多種方法,比如 二分查詢,順序查詢,斐波那契查詢,插值查詢,但是基本都是基於二分查詢的思想。接下來說一下二分的基本實現方法。二分查詢的思想其實很簡單,就是不斷地將你所要查詢的數字和你所查詢的陣列中的最中間的數字比較,如果比陣列中的中間的數字大,則將該陣列中的前面的所有的數字全部忽...

二分查詢問題

常見的二分查詢問題 1 給定排序陣列求乙個給定數在陣列中的下標,如果不存在就返回應該插入的位置 int searchinsert int a,int n,int target else return start 2 給定乙個 排序陣列,然後經過旋轉後,查詢給定值是否在陣列中。思路 1 先看左邊有序還...