LeetCode 33. 搜索旋转排序数组

33. 搜索旋转排序数组

这一题也比较简单,刚开始拿到的时候,觉得有点棘手,不敢下手,后来看了下解析,明白了思路后,就自己写了,然后一遍过了。
总的思路: 二分查找+分类讨论

1. 传统的二分法

传统的二分法十分简单,首先找到中间的,比较是否等于目标值,如果等于则返回,如果不等,则相应调整上边界或者下边界。一个简单的代码如下,但是要注意一些细节。

int BinarySearch(int nums[], int target)
{
	int low = 0, high = sizeof(nums) - 1, mid;
	while (low <= high) {
		mid = (low + high) / 2;
		if (nums[mid] == target) {
			return mid;
		}
		else if (nums[mid] > target) {
			high = mid - 1;
		}
		else
			low = mid + 1;
	}
}

2. 旋转数组的二分

此题中的数组经过了旋转,跟传统的二分就有区别。但是仍然以二分法为基础,在此基础上,情况相较于传统的更多,需要更详细的分类讨论。主要有以下几种情况:

(1) 每次划分的中间值刚好等于目标值,则直接返回;

示例如下:目标值为6。

34567012

(2) 如果不是,那么分为几种情况:
2.1 如果左半边是有序的
      2.1.1 如果目标值在这中间,那么应该在左边寻找,此时调整上边界到 mid - 1
      2.1.2 如果目标值不在这中间,那么在右边寻找,调整下边界到 mid+1

45670123

2.2 如果左半边是无序的(新的旋转数组)
      同样判断目标值是否在这中间(怎么判断:如果目标值大于最左边的或者目标值小于mid处的值,那么即在这之间);如果在,则调整上边界,如果不在则调整下边界。

67012345

### 具体代码 具体的代码如下:
class Solution {
public:
    int search(vector<int>& nums, int target) {
        // 直接循环肯定超时
        // 所以直接二分法
        bool flag = false;
        int n = nums.size();
        int low = 0, high = n - 1, mid;
        while (low <= high) {       //循环条件
            mid = (low + high) / 2;
            int m = nums[mid];
            if (m == target) {
                flag = true;
                break;
            }
            else {
                if (nums[low] <= nums[mid]) {       // 左边是有序的 
                    if (nums[low] <= target && nums[mid] >= target) {  //且target在这之间,那么在这部分二分查找
                        high = mid - 1;
                    }
                    else {          // 否则在右边查找
                        low = mid + 1;
                    }
                }
                else {  //左边是无序的
                    if (target >= nums[low] || target <= nums[mid]) {       // 若大于最左边的或小于中间的,则在左边
                        high = mid - 1;
                    }
                    else {          // 否则在右边
                        low = mid + 1;
                    }
                }
            }
        }
        if(flag)
            return mid;
        else
            return -1;
    }
};

总的来说,关键是要弄清楚几种分类情况。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值