赞
踩
左边界的获取索引函数采用low<high,右边界的获取索引函数采用low<=high
具体思路见注释
注意:左边界获取索引要注意向右侧移动后越界
右边界获取索引要注意向左侧移动后越界
两种越界都是一直没找到target导致的
如果找到了第一个满足target的索引,则以此为据点(两种不同边界考虑的算法),找左边界往左移动,找右边界往右移动
class Solution { public: vector<int> searchRange(vector<int>& nums, int target) { vector<int> range; range.push_back(searchLeft(nums,target)); range.push_back(searchRight(nums,target)); return range; } int searchLeft(vector<int> & nums, int target){ if(nums.size()==0){ return -1; } int high = nums.size(); //左闭右开,0-nums.size()-1为有效索引,但是high取size() int low = 0; int mid = 0; while(low < high){ //当nums[mid] >= target时high向左侧移动 //左侧边界设定为mid,mid已经比较过,但要保持循环的左闭右开,所以high = mid //直到low == high 时跳出循环 //此时high == low && nums[high] == nums[low] == nums[mid] == target //当nums[mid] < target时left向右侧移动,mid作为右半部分的左侧边界已经比较过 //所以新左侧边界依然要保持左闭右开,为low = mid + 1 //但是可能会出现越界的问题 //当mid == high - 1 时,此时比较的nums[mid]为nums的最后一个值 //如果他依然小于target,则low依然会加一,导致low==high,超出了nums的有效索引,此时虽然满足了跳出循环的条件,但是需要返回-1,代表一直到末尾依然没搜索到 mid = low + ((high - low)>>2);//右移两位要加括号,相当于除以2 if(nums[mid] == target){ high = mid; } else if(nums[mid] < target){ low = mid + 1; } else if(nums[mid] > target){ high = mid; } } if(low == nums.size()){ return -1; //搜索都最右侧,low越界依然没有找到 } return nums[low]==target ? low : -1; //若low未越界,则如果它的值等于target,则找到左侧边界的index,否则没找到返回-1 } int searchRight(vector<int> & nums, int target){ if(nums.size()==0){ return -1; } int high = nums.size()-1; //左闭右闭,0-nums.size()-1为有效索引 int low = 0; int mid = 0; while(low <= high){ mid = low +((high - low)>>2); if(nums[mid] == target){ low = mid + 1; } else if(nums[mid] < target){ low = mid + 1; } else if(nums[mid] > target){ high = mid - 1; } } //一直到最左侧high可能最后减一然后越界 if(high < 0){ return -1; } return nums[high]==target ? high : -1; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。