題目描述:給定一個 元素有序的(升序且有相同元素)整型數組 nums 和一個目標值 target ,寫一個函數搜索 nums 中的 target,如果目標值存在返回下標(這里指第一個等於目標值的下標),否則返回 -1。
題目分析:這道題和標准二分的差別是數組元素有重復,且需要找到第一個等於目標值的元素的下標。
提供一版正確的代碼:
class Solution { public: /** * 如果目標值存在返回下標,否則返回 -1 * @param nums int整型vector * @param target int整型 * @return int整型 */ int search(vector<int>& nums, int target) { int start = 0, end = nums.size() - 1; if (start > end || nums[start] > target || nums[end] < target) //邊界檢測 return -1; while (start <= end) { int mid = (start + end) / 2; if (nums[mid] > target)//大於的情況 { end = mid - 1; } else if (nums[mid] < target)//小於的情況 start = mid + 1; else// 等於的情況 { if (mid == 0 || nums[mid - 1] != target)//注意先判mid==0,若不成立,再判后面條件,nums[mid-1]才不會 越界 return mid; else end = mid - 1; } } return -1; } };
這里還有一版錯的代碼,但是在某平台上提交也通過了,不知道后台的case是咋跑的。
class Solution { public: /** * 如果目標值存在返回下標,否則返回 -1 * @param nums int整型vector * @param target int整型 * @return int整型 */ int search(vector<int>& nums, int target) { int start=0,end=nums.size()-1; if(start > end || nums[start] > target || nums[end] < target) //邊界檢測 return -1; while(start<=end) { int mid=(start+end)/2; if(nums[mid]>=target) { if(mid==0 && nums[mid] > target)//處理只有一個元素且比目標值大的情況 return -1; else if(mid==0 || nums[mid-1]<target)//這里 nums[mid-1]<target 滿足但不能保證 nums[mid]==target,還存在大於的情況,所以認為是錯的 return mid; else end=mid-1; } else //nums[mid]<target start=mid+1; } return -1; } };