您的位置:首页 > 其它

LeetCode 之 Search for a Range(查找)

2015-07-28 15:26 579 查看
【问题描述】

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个位置的迭代器

[code]
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++ 标准库值操作迭代器的常见函数

详址:/article/1593483.html

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: