一、 题目
给出一个已经排好序的数组和一个数字,找出在这个数字在数组中的范围。
例如:[5,7,7,8,8,10]和8
返回:[3,4]
二、 分析
题目很基础,就是找出等值的数字的开始和结束索引,上去就遍历当第一次遇到等值时记录下左索引,最后一次遇到记录下右索引也不会超时。如下:
//遍历法 class Solution { public: vector<int> searchRange(int A[], int n, int target) { vector<int> res; int k = 0; int min = -1, max = -1; while(k <= n-1){ if(A[k] == target && min == -1){ min = k; max = k; } else if(A[k] == target && min != -1){ max = k; } k++; } res.push_back(min); res.push_back(max); return res; } };
然后总觉得这样是不是没挑战力呢?那就优化吧,二分查找,找出其中一个数字,然后向左和向右找出边界即可(看到网上说的使用两次或三次二分,我感觉完全没有必要,找到一个等值接下来直接找边界就行了)。
class Solution { public: vector<int> searchRange(int A[], int n, int target) { vector<int> res; int min = -1, max = -1; int left = 0, right = n-1; int value = -1; while(left <= right){ int mid = (left + right)/2; if(A[mid] < target){ left = mid + 1; }else if(A[mid] > target){ right = mid - 1; }else if(A[mid] == target){ value = mid; break; } } if(value != -1){ for(int i = value; i < n; i++) if(A[i] == target) max = i; else break; for(int j = value; j >= 0; j--) if(A[j] == target) min = j; else break; } res.push_back(min); res.push_back(max); return res; } };
原文地址:http://blog.csdn.net/zzucsliang/article/details/43851413