搜索旋转数组

题目链接

搜索旋转数组

题目描述

注意点

  • 数组已被旋转过很多次
  • 数组元素原先是按升序排列的
  • 若有多个相同元素,返回索引值最小的一个

解答思路

  • 首先需要知道的是,本题数组中的旋转多次只是将头部的某些元素移动到尾部,所以不论怎么旋转,数组都是有一定顺序的,最差的情况是分为两段递增的子数组
  • 因为数组是有一定顺序的,所以首先考虑二分查找搜索数组,本题数组可能是两段递增的子数组组成并且数组中的元素可能重复,所以要考虑多方面:
    • 如果二分后的左区间是严格递增的:如果target在arr[left]~arr[mid]之间,说明target就在左区间内(不在左区间说明不存在),继续向左二分;否则说明target在右区间内,向右二分
    • 如果二分后的左区间是由两段递增的子数组组成的:如果target >= arr[left]或target <= arr[mid],说明target就在左区间内,继续向左二分;否则说明target在右区间内,向右二分
    • 如果二分后的左区间内的值都是相同的(arr[left] = arr[mid]):如果此时target等于该值,则直接将右边界移动到左边界即可(此时left就是结果值);否则需要不断移动左边界(每次移动一格,清除重复值)找到target

代码

java 复制代码
class Solution {
    public int search(int[] arr, int target) {
        int left = 0, right = arr.length - 1;
        while (left < right) {
            int mid = left + ((right - left) >> 1);
            // 左区间升序
            if (arr[left] < arr[mid]) {
                // 值在左区间内
                if (target >= arr[left] && target <= arr[mid]) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
                continue;
            }
            // 左区间不升序
            if (arr[left] > arr[mid]) {
                // 值在左区间内
                if (target >= arr[left] || target <= arr[mid]) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
                continue;
            }
            // 左区间值都相同 
            if (arr[left] == arr[mid]) {
                // 注意清理重复值
                if (arr[left] != target) {
                    left++;
                } else {
                    right = left;
                }
            }
        }
        return arr[left] == target ? left : -1;
    }
}

关键点

  • 二分查找的思想
  • 注意边界问题
  • 注意有多个重复的target时怎么找到最小的索引
相关推荐
转调4 分钟前
每日一练:地下城游戏
开发语言·c++·算法·leetcode
Java探秘者5 分钟前
Maven下载、安装与环境配置详解:从零开始搭建高效Java开发环境
java·开发语言·数据库·spring boot·spring cloud·maven·idea
攸攸太上5 分钟前
Spring Gateway学习
java·后端·学习·spring·微服务·gateway
2301_7869643611 分钟前
3、练习常用的HBase Shell命令+HBase 常用的Java API 及应用实例
java·大数据·数据库·分布式·hbase
2303_8120444614 分钟前
Bean,看到P188没看了与maven
java·开发语言
苹果醋314 分钟前
大模型实战--FastChat一行代码实现部署和各个组件详解
java·运维·spring boot·mysql·nginx
秋夫人16 分钟前
idea 同一个项目不同模块如何设置不同的jdk版本
java·开发语言·intellij-idea
m0_6640470221 分钟前
数字化采购管理革新:全过程数字化采购管理平台的架构与实施
java·招投标系统源码
不穿格子衬衫32 分钟前
常用排序算法(下)
c语言·开发语言·数据结构·算法·排序算法·八大排序
wdxylb39 分钟前
使用C++的OpenSSL 库实现 AES 加密和解密文件
开发语言·c++·算法