搜索旋转数组

题目链接

搜索旋转数组

题目描述

注意点

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

解答思路

  • 首先需要知道的是,本题数组中的旋转多次只是将头部的某些元素移动到尾部,所以不论怎么旋转,数组都是有一定顺序的,最差的情况是分为两段递增的子数组
  • 因为数组是有一定顺序的,所以首先考虑二分查找搜索数组,本题数组可能是两段递增的子数组组成并且数组中的元素可能重复,所以要考虑多方面:
    • 如果二分后的左区间是严格递增的:如果target在arrleft~arrmid之间,说明target就在左区间内(不在左区间说明不存在),继续向左二分;否则说明target在右区间内,向右二分
    • 如果二分后的左区间是由两段递增的子数组组成的:如果target >= arrleft或target <= arrmid,说明target就在左区间内,继续向左二分;否则说明target在右区间内,向右二分
    • 如果二分后的左区间内的值都是相同的(arrleft = arrmid):如果此时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时怎么找到最小的索引
相关推荐
云烟成雨TD6 小时前
Spring AI Alibaba 1.x 系列【69】Token 用量统计
java·人工智能·spring
Navigator_Z6 小时前
LeetCode //C - 1089. Duplicate Zeros
c语言·算法·leetcode
JAVA9656 小时前
JAVA面试-并发篇 03-使用synchronized doublecheck实现单例有什么坑
java·单例模式·面试
在繁华处6 小时前
Java从零到熟练(四):面向对象基础
java·开发语言
小江的记录本8 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
在繁华处8 小时前
Java从零到熟练(三):流程控制
java·开发语言·python
唐青枫8 小时前
Java Optional 实战指南:优雅处理空值与链式转换
java
一起学开源8 小时前
一文读懂 ReAct 范式:让 AI Agent 真正学会“思考+行动“
java·javascript·react.js·ecmascript·react·alibaba·智能体开发
云泽8089 小时前
C++ 可调用对象通关指南:深度解析 Lambda 表达式、function 包装器与 bind 绑定器
开发语言·c++·算法
wlsh159 小时前
Go 迭代器
算法