LeetCode 34 在排序陣列中查詢元素的第一個和最後一個位置
阿新 • • 發佈:2020-10-28
LeetCode 34 在排序陣列中查詢元素的第一個和最後一個位置
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
方法一:線性掃描
我們可以從左到右對陣列掃描一遍,然後記錄target所在的小標即可。掃描的結果會有一下三種情況,這三種情況以及它們對應的左右邊界情況如下:
-
陣列中不存在target——左右邊界不存在,均為-1
-
陣列中只出現一個target——左右邊界存在且相等
-
陣列中出現了兩個及以上的target——左右邊界存在且不相等
class Solution { public: // 列舉 // 時間和空間複雜度:O(N), O(1) vector<int> searchRange(vector<int>& nums, int target) { int sz = nums.size(); int lbound = -1, rbound = -1; for (int i = 0; i < sz; ++i) { if (nums[i] == target) { if (lbound == -1) lbound = i; else rbound = i; } } if (lbound != -1) return {lbound, rbound != -1 ? rbound : lbound}; else return {lbound, rbound}; } };
方法二:二分搜尋
根據題目的時間複雜度要求和陣列有序的特性,可以使用二分搜尋的方法來搜尋target在陣列中的下標。
class Solution { public: // 二分搜尋 // 時間和空間複雜度:O(logN), O(1) vector<int> searchRange(vector<int>& nums, int target) { if (nums.size() == 0) return {-1, -1}; int lbound = bound(nums, target, "left"); int rbound = bound(nums, target, "right"); return {lbound, rbound}; } int bound(vector<int>& nums, int target, string bound_type) { int sz = nums.size(); int mid, l =0, r = sz - 1; while (l <= r) { mid = (l + r) / 2; if (nums[mid] == target) { // 如果求左邊界則調整右指標往左邊界逼近;如果求右邊界則調整左指標往右邊界逼近 if (bound_type == "left") r = mid - 1; else if (bound_type == "right") l = mid + 1; } else if (nums[mid] < target) l = mid + 1; else if (nums[mid] > target) r = mid - 1; } if (bound_type == "left") { if (l >= sz || nums[l] != target) return -1; return l; } else if (bound_type == "right") { if (r < 0 || nums[r] != target) return -1; return r; } return -1; } /* // 返回左邊界下標 int left_bound(vector<int>& nums, int target) { int mid, l = 0, r = nums.size() - 1; while (l <= r) { mid = l + (r - l) / 2; if (nums[mid] == target) r = mid - 1; else if (nums[mid] < target) l = mid + 1; else if (nums[mid] > target) r = mid - 1; } if (l > nums.size() || nums[l] != target) return -1; return l; } // 返回右邊界下標 int right_bound(vector<int>& nums, int target) { int mid, l = 0, r = nums.size() - 1; while (l <= r) { mid = l + (r - l) / 2; if (nums[mid] == target) l = mid + 1; else if (nums[mid] < target) l = mid + 1; else if (nums[mid] > target) r = mid - 1; } if (r < 0 || nums[r] != target) return -1; return r; } */ };