33. 搜索旋转排序数组(二分法)

这篇具有很好参考价值的文章主要介绍了33. 搜索旋转排序数组(二分法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、算法思路

题目要求必须设计一个时间复杂度为 O(log n) 的算法解决此问题,所以我们可以采用二分法。

Step1. 先把 nums[0] 作为目标值,通过二分法找到旋转点索引;

Step2. 如果旋转点索引为0,则数组本身就是升序的,否则思想上可以将数组一分为二,看做两个升序数组。

Step3. 判断 target 目标值在一分为二后的数组的哪一个里面,从而确定左右端索引。(特殊情况:如果旋转点索引为0,则左右端索引就是 0 和 nums.length - 1)

Step4. 确认了左右端索引之后,通过二分法查找到 target 值所在索引,若不存在则返回 -1。

2、Java代码实现

public class Search {

    public static void main(String[] args) {
        Solution sol = new Solution();
        System.out.println(sol.search(new int[]{4,5,6,7,0,1,2}, 0));//4
        System.out.println(sol.search(new int[]{4,5,6,7,0,1,2}, 5));//1
        System.out.println(sol.search(new int[]{1,3,5,7,9}, 3));//1
        System.out.println(sol.search(new int[]{1,3}, 3));//1
        System.out.println(sol.search(new int[]{3,1}, 1));//1
        System.out.println(sol.search(new int[]{8,9,2,3,4}, 9));//1
        System.out.println(sol.search(new int[]{4,5,6,7,0,1,2}, 3));//-1
        System.out.println(sol.search(new int[]{1}, 0));//-1
        System.out.println(sol.search(new int[]{1,3}, 0));//-1
    }
}

// 逐一查找法
//class Solution {
//    public int search(int[] nums, int target) {
//        for (int i = 0; i < nums.length; i++) {
//            if(nums[i] == target){
//                return i;
//            }
//        }
//        return -1;
//    }
//}

// 二分查找法
class Solution {
    public int search(int[] nums, int target) {
        if (nums.length == 1){
            return nums[0] == target ? 0: -1;
        }
        // 寻找旋转点的索引
        int l = 1;
        int r = nums.length - 1;
        while(l <= r){
            int mid = l + r >> 1;
            if(nums[mid] > nums[0]) l = ++mid;
            else r = --mid;
        }

        if(l > nums.length - 1){  //旋转点为0时,数组依旧是升序排列的
            l = 0;
            r = nums.length - 1;
        }else if (target >= nums[0]){
            r = l - 1;
            l = 0;
        }else if(target <= nums[nums.length - 1]){
            r = nums.length - 1;
        }else return -1;  //target小于nums[0]又大于nums[n-1]时直接返回-1

        //target等于两边时直接返回索引
        if (nums[l] == target) return l;
        if (nums[r] == target) return r;

        // 最后进行二分查找
        while(l < r){
            int mid = l + r >> 1;
            if(nums[mid] == target) return mid;
            if(nums[mid] < target) l = ++mid;
            else r = --mid;
        }
        if(nums[l] != target) return -1;
        return l;
    }
}

3、完整题目

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

输入:nums = [4,5,6,7,0,1,2], target = 0
输出:4

示例 2:

输入:nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例 3:

输入:nums = [1], target = 0
输出:-1

提示:文章来源地址https://www.toymoban.com/news/detail-742836.html

  • 1 <= nums.length <= 5000
  • -10^4 <= nums[i] <= 10^4
  • nums 中的每个值都 独一无二
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -10^4 <= target <= 10^4

到了这里,关于33. 搜索旋转排序数组(二分法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 33.搜索旋转排序数组

    整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前, nums 在预先未知的某个下标 k ( 0 = k nums.length )上进行了 旋转 ,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能

    2024年02月01日
    浏览(34)
  • leetcode 33.搜索旋转排序数组

    🌟 leetcode链接:搜索旋转排序数组 ps: 本题是二分查找的变形,旋转排序数组之后其实会 形成两个有序的区间 。算出平均下标先判断是否与 target 相等,因为这样可以减少代码的冗余。如果前者不成立则使用平均下标元素 midIndex 与 数组最后一个元素判断大小(因为我们可

    2024年02月13日
    浏览(34)
  • LeetCode 33题:搜索旋转排序数组

    目录 题目 思路 代码 暴力解法 分方向法 二分法 整数数组  nums  按升序排列,数组中的值  互不相同  。 在传递给函数之前, nums  在预先未知的某个下标  k ( 0 = k nums.length )上进行了  旋转 ,使数组变为  [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (下标 

    2024年02月13日
    浏览(30)
  • 二分法简单题

    2024年01月24日
    浏览(39)
  • 二分法MATLAB代码

    本质是通过不断进行区间压缩来获取函数零点。 二分法的终止条件:区间长度小于等于精度要求 。 流程: 如下图所示:

    2024年02月05日
    浏览(36)
  • 初探二分法

    智能化校园:深入探讨云端管理系统设计与实现(一) 智能化校园:深入探讨云端管理系统设计与实现(二) 题目:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 提示: 你可以

    2024年01月25日
    浏览(45)
  • 【算法】—二分法详解

    ①定义: 二分查找算法也称折半搜索算法,对数搜索算法,是一种在 有序数组 中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素

    2024年02月09日
    浏览(36)
  • 二分法相关使用

    在线OJ:704. 二分查找 有序数组下的二分思路如下: 由于这里是有序数组, 我们可以可以先得到中点位置, 中点可以把数组分为左右两边; 如果中点位置的值等于目标值, 直接返回中点位置; 如果中点位置的值小于目标值, 则去数组中点左侧按同样的方式查找; 如果中点位置的值大

    2024年02月07日
    浏览(35)
  • 【二分查找】一文带你掌握二分法 (附万能模板)

    一、简介 哪怕没有学过编程的同学,也许不知道二分法这个名字,但也一定接触过它的核心思想。不了解的同学也没关系,我用一句话就能概括出它的精髓: 将一个区间一分为二,每次都舍弃其中的一部分。 二分法能够极大地降低我们在解决问题时的时间复杂度。假如你要

    2024年01月19日
    浏览(42)
  • 【剑指Offer】二分法例题

    链表是数据结构中重要的一个章节,他的重要性也不言而喻,在未来不管是笔试还是面试都会遇到这类的题目,所以接下来我就会把一些链表的常考的题目全部整理出来供大家学习指正。 题目链接 描述: 给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包

    2023年04月13日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包