题目地址: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. 力扣 - 剑指 Offer 47. 礼物的最大价值

    题目 剑指 Offer 47. 礼物的最大价值 思路1 因为是要求最大价值,而且只能移动下方或者右方,因此,每个位置的最大值就是本身的值加上上边 / 左边 中的最大值,然后每次遍历都可以复用上一次的值 ...

  2. 如何从vcf文件中批量提取一系列基因的SNP位点?

    目录 需求 示例文件 代码实现 补充说明 需求 客户的一个简单需求: 我有一批功能基因位点,想从重测序的群体材料中找到这些位点,如何批量快速获得? 示例文件 gene.txt test.vcf 代码实 ...

  3. 52-Linked List Cycle

    Linked List Cycle My Submissions QuestionEditorial Solution Total Accepted: 102785 Total Submissions ...

  4. 38- Majority Element

    Majority Element My Submissions QuestionEditorial Solution Total Accepted: 110538 Total Submissions: ...

  5. 2019java面试

    1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:    抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注 ...

  6. SpringBoot整合Shiro 二:Shiro配置类

    环境搭建见上篇:SpringBoot整合Shiro 一:搭建环境 Shiro配置类配置 shiro的配置主要集中在 ShiroFilterFactoryBean 中 关于权限: anon:无需认证就可 ...

  7. Bootstrap实战 - 瀑布流布局

    讲 Bootstrap 基础的教程网上已经很多了,实际上 Bootstrap 中文网(bootcss.com)里的文档已经写的很详细了,但实战的案例却不多.这里用一些当前流行的网页布局为导向,使用 B ...

  8. ceph对象存储场景

    安装ceph-radosgw [root@ceph-node1 ~]# cd /etc/ceph # 这里要注意ceph的源,要和之前安装的ceph集群同一个版本 [root@ceph-node1 c ...

  9. Notepad++【远程操作linux文件】

    目录 目的 预期效果 操作步骤 1.打开插件 2.安装NppFTP 3.连接远程主机 注意 目的 通过Notepad++远程登录linux主机,修改配置文件 预期效果 在Notepad++上登录lin ...

  10. Linux—禁止用户SSH登录方法总结

    Linux-禁止用户SSH登录方法总结 一.禁止用户登录 1.修改用户配置文件/etc/shadow       将第二栏设置为"*",如下.那么该用户就无法登录.但是使用这种方式 ...