牛客Top200---在旋转过的有序数组中寻找目标值(java)

题目

在这里插入图片描述

解法

看题想来想去,原来给你一颗炮弹唬你,说白了就是找nums数组中是否有target,有就返回,就是一个最简单的查找,查找最快肯定是二分查找,但二分查找的前提是有序,这个nums不是有序,而是分段有序

1、常规解

import java.util.*;

public class Solution {
   
    public int search (int[] nums, int target) {
        //遍历nums数组
        for(int i = 0 ; i < nums.length ; i++){
            if(nums[i] == target){
                return i;
            }
        }
        return -1;
    }
}

时间复杂度O(n)

2、优化(二分法)

这里就需要对二分法进行改进,我们先回顾二分法,如下

import java.util.*;

public class Solution {
    public int search (int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;
        while(left <= right){
            mid = (left+right)/2;
            if(nums[mid] < target){
                left = mid + 1;
            }else if(nums[mid] > target){
                right = mid - 1;
            }else{//==情况
                return mid;//返回下标
            }
        }
        return -1;
    }
}

时间复杂度O(logn)

本题解法
题目要求 O(logN)的时间复杂度,基本可以断定本题是需要使用二分查找,怎么分是关键。
由于题目说数字了无重复,举个例子:
1 2 3 4 5 6 7 可以大致分为两类,
第一类 2 3 4 5 6 7 1 ,也就是 nums[start] <= nums[mid]。此例子中就是 2 <= 5。
这种情况下,前半部分升序。因此如果 nums[start] <= target < nums[mid],则在前半部分找,否则去后半部分找。
第二类 6 7 1 2 3 4 5 ,也就是 nums[start] > nums[mid]。此例子中就是 6 > 2。
这种情况下,后半部分升序。因此如果 nums[mid] < target <= nums[end],则在后半部分找,否则去前半部分找。

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        int mid = 0;//初始化
        while(left <= right){
            mid = (left + right) / 2;
            if(nums[mid] == target){
                return mid;
            }
            //前半部分有序,注意=,nums[mid]也分在前半部分中,如[4,5,6,7,0,1,2]的nums[mid]=7
            if(nums[left] <= nums[mid]){
                //target在前半部分
                if(nums[left] <= target && target <= nums[mid]){
                    right = mid - 1;//right变小
                }else{
                    //target在后半部分
                    left = mid + 1;//left变大
                }
            }else{//后半部分有序
                //target在后半部分
                if(nums[mid] < target && target <= nums[right]){
                    left = mid + 1;
                }else{
                    right = mid - 1;
                }
            }
        }
        return -1;//不存在
    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小样x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值