Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
【分析】和前面两篇LeetCode类似
http://blog.csdn.net/xy010902100449/article/details/48807255
http://blog.csdn.net/xy010902100449/article/details/48806571
主要问题:
- 系统输入参数必须要做判断
- 输入数组的长度和自己求解出来数组的长度不一致
- 二分法边界问题,low 和 high 循环条件
- 和关键值 target 比较是用>= 还是用 > 问题
- 数组是降序还是增序(本题不做要求,输入都是增序的数组)
代码如下:
int lSearch(int *nums, int numsSize, int target,int flag);
int rSearch(int *nums, int numsSize, int target,int flag);
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* searchRange(int* nums, int numsSize, int target, int* returnSize)
{
*returnSize = 2;
int* returnArray = (int *)malloc((*returnSize)*sizeof(int));
// int numslen = sizeof(nums)/sizeof(int);
// printf("%d\n",numslen);
/*1.异常处理*/
if(nums==NULL|| numsSize <= 0) {
returnArray[0] = -1;
returnArray[1] = -1;
return returnArray;
}
int flag = 0;
/*1.判断数组是增序还是降序*/
if(nums[0] < nums[numsSize-1]) {
flag = 1;
}
/*数组元素完全相同*/
else if(nums[0] == nums[numsSize-1]) {
if(target == nums[0]) {
returnArray[0] = 0;
returnArray[1] = numsSize-1;
return returnArray;
}
else {
returnArray[0] = -1;
returnArray[1] = -1;
return returnArray;
}
}
else {
flag = 0;
}
/*3.二分法左右查找*/
int left = lSearch(nums,numsSize,target,flag);
int right = rSearch(nums,numsSize,target,flag);
if(-1 == left && -1 == right) {
returnArray[0] = -1;
returnArray[1] = -1;
return returnArray;
}
if(-1 == left) {
returnArray[0] = right;
returnArray[1] = right;
return returnArray;
}
if(-1 == right) {
returnArray[0] = left;
returnArray[1] = left;
return returnArray;
}
returnArray[0] = left;
returnArray[1] = right;
return returnArray;
}
int lSearch(int *nums, int numsSize, int target,int flag)
{
/*1.异常处理*/
if(nums==NULL|| numsSize <= 0 ) {
return -1;
}
int low = 0;
int high = numsSize-1;
int mid;
/*2.增序数组处理*/
if(flag) {
while(low < high) {
mid = low+(high-low)/2;
if(target <= nums[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
}
/*3.降序数组处理*/
else {
while(low < high) {
mid = low+(high-low)/2;
if(target >= nums[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
}
if(nums[low]!=target)
return -1;
return low;
}
int rSearch(int *nums, int numsSize, int target,int flag)
{
/*1.异常处理*/
if(nums==NULL|| numsSize <= 0) {
return -1;
}
int low = 0;
int high = numsSize-1;
int mid;
/*2.增序数组处理*/
if (flag) {
while(low <= high) {
mid = low+(high-low)/2;
if(target >= nums[mid]) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
}
/*3.降序数组处理*/
else {
while(low <= high) {
mid = low+(high-low)/2;
if(target <= nums[mid]) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
}
if(nums[high]!=target)
return -1;
return high;
}
完整的代码如下
// SearchforaRange.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
int lSearch(int *nums, int numsSize, int target,int flag);
int rSearch(int *nums, int numsSize, int target,int flag);
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int* searchRange(int* nums, int numsSize, int target, int* returnSize)
{
*returnSize = 2;
int* returnArray = (int *)malloc((*returnSize)*sizeof(int));
// int numslen = sizeof(nums)/sizeof(int);
// printf("%d\n",numslen);
/*1.异常处理*/
if(nums==NULL|| numsSize <= 0) {
returnArray[0] = -1;
returnArray[1] = -1;
return returnArray;
}
int flag = 0;
/*1.判断数组是增序还是降序*/
if(nums[0] < nums[numsSize-1]) {
flag = 1;
}
/*数组元素完全相同*/
else if(nums[0] == nums[numsSize-1]) {
if(target == nums[0]) {
returnArray[0] = 0;
returnArray[1] = numsSize-1;
return returnArray;
}
else {
returnArray[0] = -1;
returnArray[1] = -1;
return returnArray;
}
}
else {
flag = 0;
}
/*3.二分法左右查找*/
int left = lSearch(nums,numsSize,target,flag);
int right = rSearch(nums,numsSize,target,flag);
if(-1 == left && -1 == right) {
returnArray[0] = -1;
returnArray[1] = -1;
return returnArray;
}
if(-1 == left) {
returnArray[0] = right;
returnArray[1] = right;
return returnArray;
}
if(-1 == right) {
returnArray[0] = left;
returnArray[1] = left;
return returnArray;
}
returnArray[0] = left;
returnArray[1] = right;
return returnArray;
}
int lSearch(int *nums, int numsSize, int target,int flag)
{
/*1.异常处理*/
if(nums==NULL|| numsSize <= 0 ) {
return -1;
}
int low = 0;
int high = numsSize-1;
int mid;
/*2.增序数组处理*/
if(flag) {
while(low < high) {
mid = low+(high-low)/2;
if(target <= nums[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
}
/*3.降序数组处理*/
else {
while(low < high) {
mid = low+(high-low)/2;
if(target >= nums[mid]) {
high = mid;
}
else {
low = mid + 1;
}
}
}
if(nums[low]!=target)
return -1;
return low;
}
int rSearch(int *nums, int numsSize, int target,int flag)
{
/*1.异常处理*/
if(nums==NULL|| numsSize <= 0) {
return -1;
}
int low = 0;
int high = numsSize-1;
int mid;
/*2.增序数组处理*/
if (flag) {
while(low <= high) {
mid = low+(high-low)/2;
if(target >= nums[mid]) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
}
/*3.降序数组处理*/
else {
while(low <= high) {
mid = low+(high-low)/2;
if(target <= nums[mid]) {
low = mid + 1;
}
else {
high = mid - 1;
}
}
}
if(nums[high]!=target)
return -1;
return high;
}
int _tmain(int argc, _TCHAR* argv[])
{
int size = 2;
int* returnSize = &size;
int *returnArray = NULL;
#if 0
int nums[] = {5, 7, 7, 8, 8, 10};
#else
int nums[] = {1};
#endif
int numsSize = sizeof(nums)/sizeof(int);
int target = 0;
returnArray = searchRange(nums,numsSize ,target, returnSize);
printf("[%d ,%d]\n",returnArray[0],returnArray[1]);
free(returnArray);
getchar();
return 0;
}