leetcode每日一题(2020-4-29):1095. 山脉数组中查找目标值
2021-02-01 19:13
标签:last == -- 二分查找 复杂 参考 一个 tar 非递归 题目描述:(这是一个#交互式问题#) 给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。如果不存在这样的下标 index,就请返回 -1。 何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件: 首先,A.length >= 3 其次,在 0
你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据: 注意: 对 MountainArray.get 发起超过 100 次调用的提交将被视为错误答案。此外,任何试图规避判题系统的解决方案都将会导致比赛资格被取消。 为了帮助大家更好地理解交互式问题,我们准备了一个样例 “答案”:https://leetcode-cn.com/playground/RKhe3ave ,请注意这不是一个正确答案。 今日学习内容: 1.二分查找: leetCode.704题(升序数组的二分查找) 递归【参考百科】: 2.在排序数组中查找元素的第一个和最后一个位置 leetCode.34题(在排序数组中查找元素的第一个和最后一个位置) 3.1095山脉数组查找目标值 【参考作者:oppeuro】 leetcode每日一题(2020-4-29):1095. 山脉数组中查找目标值 标签:last == -- 二分查找 复杂 参考 一个 tar 非递归 原文地址:https://www.cnblogs.com/autumn-starrysky/p/12805132.htmlA[0] A[i+1] > ... > A[A.length - 1]
MountainArray.get(k) - 会返回数组中索引为k 的元素(下标从 0 开始)
MountainArray.length() - 会返回该数组的长度
1.二分查找
2.在排序数组中查找元素的第一个和最后一个位置
3.位运算两数中点二分查找要求:
1.必须采用顺序存储结构。
2.必须按关键字大小有序排列。
二分查找时间复杂度:
while循环的次数,即log(n)。
非递归【参考了作者:oppeuro】:var search = function(nums, target) {
var start = 0;
var end = nums.length;
if(target nums[end]){
//因为升序,target只要超过两个边界即是不存在
return -1
}
else{
//执行二分查找函数
return research(start, end-1, target, nums);
}
function research(l, r, target, nums){
//m为l和r的中点,为向下取整,因为向右移会减一
var m = (l + r) >> 1;
//中点和终点重合结束循环,判断此时中/终点的值是否为target
while(m nums[m]){
l = m + 1;
}else if(target > 1;
}
return nums[m] == target ? l : -1;
}
};
var search = function(nums, target) {
var start = 0;
var end = nums.length;
return binary(start, end-1, target, nums);
function binary(l, r, target, nums) {
if (l > 1;
if (nums[m] == target) {
return m;
} else if (nums[m] > target) {
return binary(l, m-1, target, nums);
} else {
return binary(m+1, r, target, nums);
}
}
return -1;
}
};
利用二分查找,若找到目标值则继续向前/后遍历是否还存在目标值。var searchRange = function(nums, target) {
let low =0
let high = nums.length-1;
let list = []
while(low
/*
第一次查 分3种情况:查到正中间,查到左边,查到右边
1. 查到正中间(最简单的)左边递增右边递减,做两次二分即可。
2. 查到左侧分情况 如果查的数小于当前值,(左侧 -> 当前做二分)-(当前值 -> 右侧 看成一个新的山脉数组)
3. 查到右侧分情况 如果查的数大于当前值,(左侧 -> 当前值 看成一个新山脉数组)- (当前值 -> 右侧做二分)
*/
var findInMountainArray = function(target, mountainArr, start = 0, end = mountainArr.length()) {
// 递归出口,只有两值的时候直接求解即可
if(start > end) return -1;
if(end - start == 2){
if(mountainArr.get(start) == target) return start;
if(mountainArr.get(end - 1) == target) return end - 1;
return -1;
}
// 查找数组的范围, 中间值的前一值,中间值,中间值的后一值;通过这个3值确定当前位置。
let l = start, r = end, m = (l + r) >> 1,
last = mountainArr.get(m - 1), now = mountainArr.get(m), next = mountainArr.get(m + 1);
// 正中间
if(last now) return -1;
if(target == now) return m;
let left = seachLowToHeight(l, m, target, mountainArr);
return left == -1 ? seachHeightToLow(m + 1, r, target, mountainArr) : left;
}
// 左边
if(last now){
return findInMountainArray(target, mountainArr, m + 1, r);
}
}
// 右边
if(last > now && now > next){
let left = findInMountainArray(target, mountainArr, l, m);
if(target == now){
return left == -1 ? m : left;
}
if(target now){
return left == -1 ? seachHeightToLow(l, m, target, mountainArr) : left;
}
}
return -1;
};
// 两个二分辅助函数,一个是小到大二分,一个是大到小二分
function seachLowToHeight(l, r, target, mountainArr){
let m = (l + r) >> 1, val = mountainArr.get(m);
while(l target){
r = m;
}
m = (l + r) >> 1;
val = mountainArr.get(m);
}
return val == target ? l : -1;
}
function seachHeightToLow(l, r, target, mountainArr){
let m = (l + r) >> 1, val = mountainArr.get(m);
while(l target){
l = m + 1;
}
m = (l + r) >> 1;
val = mountainArr.get(m);
}
return val == target ? l : -1;
}
下一篇:java实现发送短信
文章标题:leetcode每日一题(2020-4-29):1095. 山脉数组中查找目标值
文章链接:http://soscw.com/index.php/essay/49614.html