【LeetCode】1095. 山脉数组中查找目标值 Find in Mountain Array
- 作者: 负雪明烛
- id: fuxuemingzhu
- 个人博客:http://fuxuemingzhu.cn/
题目地址:https://leetcode-cn.com/problems/find-in-mountain-array/
题目描述
给你一个 山脉数组 mountainArr
,请你返回能够使得 mountainArr.get(index)
等于 target
最小 的下标 index
值。
如果不存在这样的下标 index
,就请返回 -1
。
何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件:
- 首先,
A.length >= 3
- 其次,在
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。
提示:
3 <= mountain_arr.length() <= 10000
0 <= target <= 10^9
0 <= mountain_arr.get(index) <= 10^9
题目大意
在一个山形的数组上,找出 target 元素第一次出现的位置。
解题方法
二分查找
这个题疯狂提示用二分查找。
提示1. 山脉数组的左右两部分分别有序
提示2. array数组总长度是 10000,总的读取元素的次数不超过 100 次。
根据这两点,我们可以 100% 地确定用二分查找方法。
题目的难点在于找到 target 出现的第一个位置,如果我们想着只在山峰的左边或者右边使用一次二分查找的话,没法确定一次就就查找到。因此必须在山峰的左右两边都进行二分查找。
那么思路就是:
- 找到山峰的位置
- 在山峰的左边查找 target
- 如果查找不到,则在山峰的右边查找 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的更多相关文章
- Leetcode算法【34在排序数组中查找元素】
在之前ARTS打卡中,我每次都把算法.英文文档.技巧都写在一个文章里,这样对我的帮助是挺大的,但是可能给读者来说,一下子有这么多的输入,还是需要长时间的消化. 那我现在改变下方式,将每一个模块细分化, ...
- [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 ...
- Java实现 LeetCode 34 在排序数组中查找元素的第一个和最后一个位置
在排序数组中查找元素的第一个和最后一个位置 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n ...
- LeetCode二维数组中的查找
LeetCode 二维数组中的查找 题目描述 在一个 n*m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增.请完成一个搞笑的函数,输入这样的一个二维数组和一个整数,判断数 ...
- [LeetCode]面试题53 - I. 在排序数组中查找数字 I(二分);面试题53 - II. 0~n-1中缺失的数字(二分)
##面试题53 - I. 在排序数组中查找数字 I ###题目 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 ...
- 【LeetCode】34. 在排序数组中查找元素的第一个和最后一个位置
34. 在排序数组中查找元素的第一个和最后一个位置 知识点:数组,二分查找: 题目描述 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置 ...
- 剑指offer--二维数组中查找
剑指offer--二维数组中查找 题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序, 每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组 ...
- 每日一题 - 剑指 Offer 53 - I. 在排序数组中查找数字 I
题目信息 时间: 2019-07-04 题目链接:Leetcode tag:二分查找 哈希表 难易程度:简单 题目描述: 统计一个数字在排序数组中出现的次数. 示例1: 输入: nums = [5,7 ...
- java语言在某个数组中查找某个字符出现的次数
package com.llh.demo; import java.util.Scanner; /** * * @author llh * */ public class Test { /* * 在某 ...
随机推荐
- printf 的 转义词 -转
\n 换行 \r 回车键 \b 退后一格 \f 换页 \t 水平制表符 \v 垂直制表符 \a 发出鸣响 \? 插入问号 \" 插入双引号 \' ...
- docker可视化管理Portainer
Portainer是一款轻量级docker容器管理平台,占用资源少,支持集群,支持权限分配. $ docker volume create portainer_data$ docker run -d ...
- 字符串String的trim()方法
用来删除字符串两端的空白字符并返回,trim方法并不影响原来的字符串本身,它返回的是一个新的字符串 String a = " Hello World "; String b = ...
- UE4之Slate: App启动与最外层Runtime结构
UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...
- nodeJs,Express中间件是什么与常见中间件
中间件的功能和分类 中间件的本质就是一个函数,在收到请求和返回相应的过程中做一些我们想做的事情.Express文档中对它的作用是这么描述的: 执行任何代码.修改请求和响应对象.终结请求-响应循环.调用 ...
- 【leetcode】1217. Minimum Cost to Move Chips to The Same Position
We have n chips, where the position of the ith chip is position[i]. We need to move all the chips to ...
- linux之sar命令详解
sar(System Activity Reporter系统活动情况报告)是目前Linux上最为全面的系统性能分析工具之一,可以从多个方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情况 ...
- MapStruct对象转换
第一次看到 MapStruct 的时候, 我个人非常的开心.因为其跟我内心里面的想法不谋而合. 1 MapStruct 是什么? 1.1 JavaBean 的困扰 对于代码中 JavaBean之间的转 ...
- 集合类——集合输出、栈和队列及Collections集合
1.集合输出 在之前我们利用了toString()及get()方法对集合进行了输出,其实那都不是集合的标准输出,集合输出有四种方式:Iterator.ListIterator.Enumeration. ...
- k8s之ansible安装
项目地址:https://github.com/easzlab/kubeasz #:先配置harbor #:利用脚本安装docker root@k8s-harbor1:~# vim docker_in ...