• Search in Rotated Sorted Array


    Suppose a sorted array is rotated at some pivot unknown to you beforehand.

    (i.e., 01 2 4 5 6 7 might become 4 5 6 7 0 1 2).

    You are given a target value to search. If found in the array return its index,otherwise return -1.

    You may assume no duplicate exists in the array.

     

    思路:本题还是在考察二分查找。在一个经过旋转后的数组中寻找某个值,首先需要找到“旋转点”,比如在数组 4 5 6 7 0 1 2中,0元素的索引,也就是4,即是我们需要首先找到的“旋转点”。找到旋转点之后,整个数组就分为两个子数组,一是旋转点之前的数组,另一个是旋转点之后的数组。这两个数组都是按序递增的,因此只要分别在这两个数组上使用二分查找即可。


    如何寻找旋转点,也需要使用二分查找的变种,二分查找之所以这么快,就是因为它每次都去掉了一半的可能性。


    在寻找旋转点时,还是要看中点的值set[mid],如果set[left]<=set[mid],set[right]<=set[mid],比如上例中的45 6 7 0 1 2,这说明当前的中点在旋转点的左边,因此需要left = mid+1。


    如果set[left]>=set[mid],set[right]>=set[mid],比如6 7 0 1 2 4 5,这说明当前的中点在旋转点的右边,因此需要right = mid-1。


    如果set[left]<=set[mid]<=set[right],则说明当前的left和right已经完全处于某个子数组之中了,这时就是结束寻找的时候了,因left或者right都是针对上次的mid值前进或后退一步得来的,说明left或者right就是该子数组的边界,具体哪个才是要找的旋转点,就看本次到底是left向前走还是right向后走得到的,代码如下:

    int findrotate(int *sets, int nums)
    {
    	int left = 0, right = nums-1;
    	int mid, lastmid = -1;
    
    	while(left <= right)
    	{
    		mid = left + (right-left)/2;
    		if(sets[left] <= sets[mid] && sets[mid] <= sets[right])	break;
    
    		if(sets[mid] >= sets[left] && sets[mid] >= sets[right])
    		{
    			left = mid+1;
    			lastmid = mid;
    		}
    		else
    		{
    			right = mid-1;
    			lastmid = mid;
    		}
    	}
    
    	if(mid < lastmid)	return lastmid;
    	else 		return lastmid+1;
    }
    
    int search(int* nums, int numsSize, int target) 
    {
    	int left[2], right[2];
    	int start, end, mid;
    	left[1] = findrotate(nums, numsSize);
    	left[0] = 0;
    	right[0] = left[1]-1;
    	right[1] = numsSize-1;
    
    	int i = 0;
    	for(i = 0; i < 2; i++)
    	{
    		start = left[i];
    		end = right[i];
    	
    		while(start <= end)
    		{
    			mid = start + (end-start)/2;
    			if(nums[mid] == target)	return mid;
    			if(nums[mid] < target)
    			{
    				start = mid+1;
    			}
    			else
    			{
    				end = mid-1;
    			}
    		}
    	}
    	return -1;
    }


  • 相关阅读:
    致歉
    博客园上海俱乐部活动报道
    博客园手机版
    味道不错的NBearLite查询语法
    关于面向对象的讨论
    变形金刚皮肤
    准备在北京Tech·Ed上组织博客园聚会
    SVN&.NET
    博客园手机版功能更新
    最省时管理法:让你一天随意
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247145.html
Copyright © 2020-2023  润新知