题目地址:https://leetcode-cn.com/problems/find-in-mountain-array/

题目描述

给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。

如果不存在这样的下标 index,就请返回 -1

何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件:

  1. 首先,A.length >= 3
  2. 其次,在 0 < i < A.length - 1 条件下,存在 i 使得:
  • A[0] < A[1] < ... A[i-1] < A[i]
  • A[i] > A[i+1] > ... > A[A.length - 1]

你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据:

  • MountainArray.get(k) - 会返回数组中索引为k 的元素(下标从 0 开始)
  • MountainArray.length() - 会返回该数组的长度

注意:

对 MountainArray.get 发起超过 100 次调用的提交将被视为错误答案。此外,任何试图规避判题系统的解决方案都将会导致比赛资格被取消。

为了帮助大家更好地理解交互式问题,我们准备了一个样例 “答案”:https://leetcode-cn.com/playground/RKhe3ave,请注意这 不是一个正确答案。

示例 1:

输入:array = [1,2,3,4,5,3,1], target = 3
输出:2
解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。

示例 2:

输入:array = [0,1,2,4,2,1], target = 3
输出:-1
解释:3 在数组中没有出现,返回 -1。

提示:

  1. 3 <= mountain_arr.length() <= 10000
  2. 0 <= target <= 10^9
  3. 0 <= mountain_arr.get(index) <= 10^9

题目大意

在一个山形的数组上,找出 target 元素第一次出现的位置。

解题方法

二分查找

这个题疯狂提示用二分查找。
提示1. 山脉数组的左右两部分分别有序
提示2. array数组总长度是 10000,总的读取元素的次数不超过 100 次。
根据这两点,我们可以 100% 地确定用二分查找方法。

题目的难点在于找到 target 出现的第一个位置,如果我们想着只在山峰的左边或者右边使用一次二分查找的话,没法确定一次就就查找到。因此必须在山峰的左右两边都进行二分查找。

那么思路就是:

  1. 找到山峰的位置
  2. 在山峰的左边查找 target
  3. 如果查找不到,则在山峰的右边查找 target

二分法是个经典的模板问题。推荐使用 二分查找模板2

找到山峰的位置可以根据 mid 元素处于上坡还是下坡来识别出来。在左右两部分进行查找 target 就是普通的二分,唯一需要注意的是 左边是递增的,右边是递减的,二分查找的判断不要出错。

Python 代码如下:

# """
# This is MountainArray's API interface.
# You should not implement it, or speculate about its implementation
# """
#class MountainArray:
# def get(self, index: int) -> int:
# def length(self) -> int: class Solution:
def findInMountainArray(self, target: int, nums: 'nums') -> int:
N = nums.length()
peek = self.findPeek(target, nums)
left_index = self.findInAscOrder(target, nums, 0, peek)
right_index = self.findInDecOrder(target, nums, peek, N - 1)
if left_index != -1:
return left_index
else:
return right_index def findPeek(self, target, nums):
N = nums.length()
left, right = 1, N - 2
while left <= right:
mid = left + (right - left) // 2
if nums.get(mid - 1) < nums.get(mid) > nums.get(mid + 1):
return mid
elif nums.get(mid - 1) < nums.get(mid) < nums.get(mid + 1):
left = mid + 1
else:
right = mid - 1
return left def findInAscOrder(self, target, nums, begin, end):
left, right = begin, end
while left <= right:
mid = left + (right - left) // 2
print(left, right, mid)
cur = nums.get(mid)
if cur == target:
return mid
elif cur < target:
left = mid + 1
else:
right = mid - 1
return -1 def findInDecOrder(self, target, nums, begin, end):
left, right = begin, end
while left <= right:
mid = left + (right - left) // 2
cur = nums.get(mid)
if cur == target:
return mid
elif cur < target:
right = mid - 1
else:
left = mid + 1
return -1

欢迎关注负雪明烛的刷题博客,leetcode刷题800多,每道都讲解了详细写法!

日期

2020 年 4 月 29 日 —— 连续刷二分

【LeetCode】1095. 山脉数组中查找目标值 Find in Mountain Array的更多相关文章

  1. Leetcode算法【34在排序数组中查找元素】

    在之前ARTS打卡中,我每次都把算法.英文文档.技巧都写在一个文章里,这样对我的帮助是挺大的,但是可能给读者来说,一下子有这么多的输入,还是需要长时间的消化. 那我现在改变下方式,将每一个模块细分化, ...

  2. [LeetCode] 34. Find First and Last Position of Element in Sorted Array 在有序数组中查找元素的第一个和最后一个位置

    Given an array of integers nums sorted in ascending order, find the starting and ending position of ...

  3. Java实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置

    在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n ...

  4. LeetCode二维数组中的查找

    LeetCode 二维数组中的查找 题目描述 在一个 n*m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增.请完成一个搞笑的函数,输入这样的一个二维数组和一个整数,判断数 ...

  5. [LeetCode]面试题53 - I. 在排序数组中查找数字 I(二分);面试题53 - II. 0~n-1中缺失的数字(二分)

    ##面试题53 - I. 在排序数组中查找数字 I ###题目 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 ...

  6. 【LeetCode】34. 在排序数组中查找元素的第一个和最后一个位置

    34. 在排序数组中查找元素的第一个和最后一个位置 知识点:数组,二分查找: 题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置 ...

  7. 剑指offer--二维数组中查找

    剑指offer--二维数组中查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序, 每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组 ...

  8. 每日一题 - 剑指 Offer 53 - I. 在排序数组中查找数字 I

    题目信息 时间: 2019-07-04 题目链接:Leetcode tag:二分查找 哈希表 难易程度:简单 题目描述: 统计一个数字在排序数组中出现的次数. 示例1: 输入: nums = [5,7 ...

  9. java语言在某个数组中查找某个字符出现的次数

    package com.llh.demo; import java.util.Scanner; /** * * @author llh * */ public class Test { /* * 在某 ...

随机推荐

  1. 有限元边界 Dirichlet 条件处理

    参考自百度文档,这里只考虑 Dirichlet 边界条件情况. 有限元法基本方法就是是构造线性方程组 \[\begin{equation} Au = f \end{equation}\] 进行求解.其 ...

  2. python-django-数据查询条件

    查询用户的状态是2或者是4的情况 空值和空字符串是不一样的东西!!! 需要注意的是: 项目setting.py里面的时区采用的是美国的时区,我们不要使用这个时区 使用这个时区的,我们输入的日期会进行转 ...

  3. rust shadow

    1 fn main() { 2 let mut demo = 12; 3 println!("{}",demo); 4 demo = 21; // 值可变,数据类型不可变 5 pr ...

  4. matplotlib 画饼图

    有个瑕疵,某一块儿比例过小时,文字会重叠. 1 def pizza(data,labs,title): 2 import matplotlib 3 import matplotlib.pyplot a ...

  5. brew 切换源

    切换到国内源 # 替换brew.git: $ cd "$(brew --repo)" # 中国科大: $ git remote set-url origin https://mir ...

  6. 推荐一个latex简历模板的网站给大家

    http://www.rpi.edu/dept/arc/training/latex/resumes/ Using the LaTeX Resume Templates A group of resu ...

  7. 数据集成工具—FlinkX

    @ 目录 FlinkX的安装与简单使用 FlinkX的安装 FlinkX的简单使用 读取mysql中student表中数据 FlinkX本地运行 MySQLToHDFS MySQLToHive MyS ...

  8. Flume对接Kafka

    目录 一.简单实现 1)flume的配置文件 二.自定义interceptor(使用kafka sink) 1)自定义 flume 拦截器 2)编写 flume 的配置文件 3)创建topic 4)启 ...

  9. Swagger2异常 java.lang.NumberFormatException: For input string: ""

    问题在访问swagger首页时报错: java.lang.NumberFormatException: For input string: "" at java.lang.Numb ...

  10. 【leetcode】834. Sum of Distances in Tree(图算法)

    There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges. You are ...