LeetCode 之 Search for a Range(查找)

【问题描述】

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].

1.【基础知识】

1)熟练掌握二分查找思想与源码

详见:数据结构基础 查找 之 二分查找

详址:http://blog.csdn.net/u013630349/article/details/47101881

2.【屌丝代码】

实现失败!

未实现原因:

1)不能处理好 mid、high、low 三者之间的关系;

2)不能处理好 边际条件 在 单变量、边界变量 查找的时候。

解决思路:

1)mid 递增和递减步骤;

2)mid 在采用非递归算法的时候,high作为上界值为size(),采用递归算法的时候值为size()-1;

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) 
	{
        int i;
		vector<int> myvec;
		if (nums.empty())
		{
			myvec.push_back(-1);
			myvec.push_back(-1);
			return myvec;
		}
		int low(0),high(nums.size()-1);
		if (nums[low]>target||nums[high]<target)
		{
			myvec.push_back(-1);
			myvec.push_back(-1);
			return myvec;
		}
		int mid = low+high/2,ind;
		while(high>=low)
		{
			if(target == nums[high])
			{	
				ind = high;
				break;
			}
			if(target > nums[mid])
			{
				low = mid;
				mid = (low+high)/2;
			}
			if(target == nums[high])
			{
				high = mid;
				mid = (low+high)/2;
			}
			if(target == nums[mid])
			{
				ind = mid;
				break;
			}
		}		
    	int max(ind),min(ind);
		for(i = ind;i<nums.size()&&nums[i] == nums[ind];i++)
		{
			max = i;
		}
		for(i = ind;i>0&&nums[i]==nums[ind];i--)
		{
			min = i;
		}
		for(i=min;i<=max;i++)
		{
			myvec.push_back(i);
		}
		for(i=0;i<myvec.size();i++)
		{
			cout<<myvec[i]<<endl;
		}
		return myvec;
	}
};

3.【源码AC】

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        const int l = distance(nums.begin(), lower_bound(nums.begin(), nums.end(), target));
        const int u = distance(nums.begin(), prev(upper_bound(nums.begin(), nums.end(), target)));
        if (nums[l] != target) // not found
        	return vector<int> { -1, -1 };
        else
        	return vector<int> { l, u };
    }
};

lower_bound 算法返回一个非递减序列[first, last)中的第一个大于等于 val 的位置。 

upper_bound 算法返回一个非递减序列[first, last)中的第一个大于 val 的位置。

distance算法返回两个输入参数的相对物理地址;

关于 prev 方法

If it is a random-access iterator, the function uses just once operator+ or operator-. Otherwise, the function uses repeatedly the increase or decrease operator (operator++ or operator--) on the copied iterator until n elements have been advanced.

【译】

如果是随机访问迭代器,就只执行一次运算符操作,否则,执行n次持续的递减或递增操作。

Random-access iterators are iterators that can be used to access elements at an arbitrary offset position relative to the elementthey point to, offering the same functionality as pointers.

【译】

随机访问迭代器是一种可以访问距离迭代器所指元素任意偏移地址元素的迭代器,其功能类似于指针。

prev函数:返回迭代器的前n个位置的迭代器

template <class BidirectionalIterator>
  BidirectionalIterator prev (BidirectionalIterator it,
       typename iterator_traits<BidirectionalIterator>::difference_type n = 1);

例:

要返回上述vector的最后一个元素:

cout  << prev(A.end() )  << endl;

要返回上述vector的倒数第3个元素:

cout  << prev(A.end() , 3)  << endl;

#include <iostream>     // std::cout
#include <iterator>     // std::next
#include <list>         // std::list
#include <algorithm>    // std::for_each


int main () {
  std::list<int> mylist;
  for (int i=0; i<10; i++) mylist.push_back (i*10);

  std::cout << "The last element is " << *std::prev(mylist.end()) << '\n'; // 90

  return 0;
}

关于advance方法

#include <iostream>     // std::cout
#include <iterator>     // std::advance
#include <list>         // std::list

int main () {
  std::list<int> mylist;
  for (int i=0; i<10; i++) mylist.push_back (i*10);

  std::list<int>::iterator it = mylist.begin();
  std::advance (it,3);  
  std::cout << "The sixth element in mylist is: " << *it << '\n';// 30
  it = mylist.end();  
  std::advance (it,-3);
  std::cout << "The sixth element in mylist is: " << *it << '\n';// 70

  return 0;
}

迭代器常见函数:

详见:C++ 标准库值操作迭代器的常见函数

详址:http://blog.csdn.net/xuqingict/article/details/32730477

4.【复盘】

1)卡壳部分
a.二分查找不熟悉,知识点记忆模糊,尤其是在mid的处理上;

b.在常见情况处理完毕后,尽量将特殊情况归一到常规处理之中,保证处理的统一性,实在丢不进去也无可厚非,添添补补能用即可,结果导向是第一位的!

2)算法思想

a.找到第一个等于该变量的索引'l',找到第一个大于该变量的索引'h'+1;

b.如果,第一个等于该变量的索引未找到,返回{-1,-1},如果第一个大于该变量的索引未找到,则'h'+1=nums.size();

c.输出{l,h}即可;

3)后记

详见:C++ STL 迭代器方法 之 advance与prev 方法 浅析

详址:http://blog.csdn.net/u013630349/article/details/47105319

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值