Leetcode刷题记—— 33. Search in Rotated Sorted Array(在翻转顺序的数组里查找)

一、题目叙述:

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

(i.e., 0 1 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.

Subscribe to see which companies asked this question

给定一个按某个轴翻转了顺序的排序数组,求给定值在数组中的索引位置,若不存在,返回-1。

二、解题思路(参考别人的思路):

本题是二分查找应用的变体,主要难度在思考出方法上。。。

首先,将问题抽象化,对于一个区间[l, r],我们希望能够找到这段区间中最小数的坐标,不妨称为q[l, r],

令 m = (l + r) / 2, 首先我们来看这段区间的构成:

  1. 如果 a[l] < a[r],说明这段区间是有序的,容易知道 q[l, r] = l

  2. 如果 a[l] > a[r],说明这段区间是由两段有序区间组成的,此时我们分情况讨论:

2.1 如果 a[m] >= a[l],说明 m 处于左侧(即较高)的一段有序区间中,因为最小值一定在较低的有序区间中,我们可以知道 q[l, r] = q[m + 1, r]。

2.2 如果 a[m] < a[l],说明 m 处于右侧(即较低)的一段有序区间中,但因为 a[m] 一定满足 a[m] <= a[r],即[m + 1, r]中的所有元素都不会是最小值,我们可以知道q[l, r] = q[l, m]。

由于在这样的处理中,每次问题的规模都被缩小了一半,所以最终我们一定会遇到一个问题q[l, r]满足l=r,此时我们就可以知道区间中最小数的坐标为l。

3、找到最小数的坐标,我们就可以像正常的二分查找方式一样对数组进行查找搜索,只是在计算得到mid值时稍加计算,以得到真正大小顺序为mid的数组下标,即(mid + l)% nums.length;

三、源码:

public class Solution 
{
    public int search(int[] nums, int target)
    {
        int l = 0;
        int r = nums.length - 1;
        while (l < r)
        {
        	if (nums[l] < nums[r])  r = l;
        	else
        	{
        		int mid = l + (r - l) / 2;
        		if (nums[mid] >= nums[l]) l = mid + 1;
        		else if (nums[mid] < nums[l]) r = mid;
        	}
        }
        return find(nums, target, l);
    }
    public int find(int[] nums, int target, int l)
    {
    	int l1 = 0;
    	int r1 = nums.length - 1;
    	while (l1 <= r1)
    	{
    		int mid = l1 + (r1 - l1) / 2;
    		int temp = (l + mid) % nums.length;
    		if (nums[temp] == target) return temp;
    		else if (nums[temp] > target) r1 = mid - 1;
    		else l1 = mid + 1;
    	}
    	return -1;
    }
    public static void main(String args[])
    {
    	int[] nums = {};
    	int target = 9;
    	Solution solution = new Solution();
    	System.out.println(solution.search(nums, target));
    
    }
}
	


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值