日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[二分查找] 二:二分查找的经典例题

發布時間:2025/6/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [二分查找] 二:二分查找的经典例题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.何時應該會使用二分查找

  • 當題目中出現有序數組時
  • 當時間復雜度要求為log(n)時
  • 搜索范圍可以一次縮小一半時

2. 經典例題1

給定一個排序數組和一個目標值,在數組中找到目標值,并返回其索引。如果目標值不存在于數組中,返回它將會被按順序插入的位置。

請必須使用時間復雜度為 O(log n) 的算法。

示例 1:
輸入: nums = [1,3,5,6], target = 5
輸出: 2

示例 2:
輸入: nums = [1,3,5,6], target = 2
輸出: 1

示例 3:
輸入: nums = [1,3,5,6], target = 7
輸出: 4

示例 4:
輸入: nums = [1,3,5,6], target = 0
輸出: 0

示例 5:
輸入: nums = [1], target = 0
輸出: 0

此題為最經典的二分查找

int searchInsert(vector<int>& nums, int target) {int left = 0, right = nums.size();while(left < right){int mid = (left+right)/2;if(target == nums[mid]) return mid;else if(target > nums[mid]){left = mid + 1;}else {right = mid;}}return left; }

3. 經典例題2

整數數組 nums 按升序排列,數組中的值互不相同。
在傳遞給函數之前,nums 在預先未知的某個下標k(0 <= k < nums.length)上進行了 旋轉,使數組變為 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下標 從 0 開始 計數)。

例如, [0,1,2,4,5,6,7] 在下標 3 處經旋轉后可能變為 [4,5,6,7,0,1,2] 。

給你 旋轉后 的數組 nums 和一個整數 target ,如果 nums 中存在這個目標值 target ,則返回它的下標,否則返回 -1 。要求時間復雜度為log(n)。

示例 1:
輸入:nums = [4,5,6,7,0,1,2], target = 0
輸出:4

示例 2:
輸入:nums = [4,5,6,7,0,1,2], target = 3
輸出:-1

示例 3:
輸入:nums = [1], target = 0
輸出:-1

題目要求我們的時間復雜度為log(n),所以我們很快能想到和二分查找有關。數組nums一開始為有序的,但是經過旋轉之后不再整體有序,變成了兩個有序的部分。

這種情況下我們每次二分先檢查有序的那一半(至少有一半是有序的),如果要找的值正好在有序的這部分(比較左右邊界即可判斷出目標值是否在有序部分),則收縮邊界,再進行二分查找。如果不在有序的部分,則再考慮無序的部分,無序的部分可以再分為兩個部分,其中又有一半一定是有序的,剩下的步驟與前面一樣

int search(vector<int>& nums, int target) {int left = 0, right = nums.size()-1;while(left <= right){int mid = (left+right)/2;if(nums[mid] == target) return mid;//說明mid左邊有序if(nums[mid] >= nums[left]){//判斷目標值是否在有序部分if(nums[mid] > target && nums[left] <= target){right = mid - 1;}else left = mid + 1;}//說明mid右邊有序else{//判斷目標值是否在有序部分if(nums[mid] < target && nums[right] >= target){left = mid + 1;}else right = mid - 1;}}return -1; }

3. 經典例題3

給定兩個大小分別為 m 和 n 的正序(從小到大)數組 nums1 和 nums2。請你找出并返回這兩個正序數組的 中位數 。

算法的時間復雜度應該為 O(log (m+n)) 。

示例 1:
輸入:nums1 = [1,3], nums2 = [2]
輸出:2.00000
解釋:合并數組 = [1,2,3] ,中位數 2

示例 2:
輸入:nums1 = [1,2], nums2 = [3,4]
輸出:2.50000
解釋:合并數組 = [1,2,3,4] ,中位數 (2 + 3) / 2 = 2.5

示例 3:
輸入:nums1 = [0,0], nums2 = [0,0]
輸出:0.00000

示例 4:
輸入:nums1 = [], nums2 = [1]
輸出:1.00000

示例 5:
輸入:nums1 = [2], nums2 = []
輸出:2.00000

兩個數組長度是固定的,所以中位數的位置也是固定的。當兩數組長度之和為奇數時,中位數下標為:(totalLength + 1) / 2,若為偶數,中位數為 (nums[totalLength / 2] + nums[(totalLength + 1) / 2])/2

要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 進行比較

  • 這里的 “/” 表示整除
  • nums1 中小于等于 pivot1 的元素有 nums1[0 … k/2-2] 共計 k/2-1 個
  • nums2 中小于等于 pivot2 的元素有 nums2[0 … k/2-2] 共計 k/2-1 個
  • 取 pivot = min(pivot1, pivot2),兩個數組中小于等于 pivot 的元素共計不會超過 (k/2-1) + (k/2-1) <= k-2 個,這樣 pivot 本身最大也只能是第 k-1 小的元素
  • 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把這些元素全部 “刪除”,剩下的作為新的 nums1 數組
  • 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把這些元素全部 “刪除”,剩下的作為新的 nums2 數組
  • 由于我們 “刪除” 了一些元素(這些元素都比第 k 小的元素要小),因此需要修改 k 的值,減去刪除的數的個數,搜索區間每次縮短了一半 k=k-k/2。
int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {int m = nums1.size(), n = nums2.size();int index1 = 0, index2 = 0;while(true){if(index1 == m){return nums2[index2 + k - 1];}else if(index2 == n){return nums1[index1 + k - 1];}else if(k == 1){return min(nums1[index1], nums2[index2]);}int newIndex1 = min(index1 + k / 2 - 1, m - 1);int newIndex2 = min(index2 + k / 2 - 1, n - 1);int pivot1 = nums1[newIndex1];int pivot2 = nums2[newIndex2];if (pivot1 <= pivot2) {k -= newIndex1 - index1 + 1;index1 = newIndex1 + 1;}else {k -= newIndex2 - index2 + 1;index2 = newIndex2 + 1;}}}double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {int totalLength = nums1.size() + nums2.size();if (totalLength % 2 == 1) {return getKthElement(nums1, nums2, (totalLength + 1) / 2);}else {return (getKthElement(nums1, nums2, totalLength / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;}} 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的[二分查找] 二:二分查找的经典例题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。