由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - 问一道求数组拐点值的题
相关主题
一个题search in a rotated array
G家phone interview经验,攒人品[算法]二分搜索变体
找个先增后减的数组里的数。find median for k sorted arrays
问一道题(5)谁给个数组分段题二分法的总结啊?
求函数的极值那题的解法?贡献西部小公司面筋
关于最长递增子序列的问题。问一个我onsite的题
F家onsite悲剧了,求refer新鲜亚麻店面面经
你们刷题都刷傻了, 那么简单的题目都做错请教大家一个算法的面试题目
相关话题的讨论汇总
话题: mid话题: left话题: right话题: turnpoint话题: 拐点
进入JobHunting版参与讨论
1 (共1页)
w*****t
发帖数: 485
1
不记得是哪家的了:
给定一个函数,f(x),x在某值之前是非递减的,在某值之后是非递增的。设计一个算法
快速查找这个值。
求拐点值,如: "1,2,3,4,5,4,3,2,1", --> 5
"1,1,1,1,1,2,1,1" --> 2
"1,2,1,1,1,1,1,1" --> 2
有 log(N)的解法吗?
l******n
发帖数: 9344
2
做一阶difference
b(i)=a(i+1)-a(i)
然后二分就可以了

【在 w*****t 的大作中提到】
: 不记得是哪家的了:
: 给定一个函数,f(x),x在某值之前是非递减的,在某值之后是非递增的。设计一个算法
: 快速查找这个值。
: 求拐点值,如: "1,2,3,4,5,4,3,2,1", --> 5
: "1,1,1,1,1,2,1,1" --> 2
: "1,2,1,1,1,1,1,1" --> 2
: 有 log(N)的解法吗?

x****g
发帖数: 1512
3
有点晕.
如果做过a(i+1)-a(i)就已经是O(N)了.
再二分意义何在?
直接二分不行吗?

【在 l******n 的大作中提到】
: 做一阶difference
: b(i)=a(i+1)-a(i)
: 然后二分就可以了

c*****e
发帖数: 67
4
直接二分:
left和right先skip掉相同的数,
然后left, right取mid,看mid的左[mid-1]右[mid+1]:
如果左右都小,则找到;
如果左小右大,则在非递减部分,更新left=mid+1
如果左大右小,则在非递增部分,更新right=mid-1
贴个js代码不知道有没有bug,有的话麻烦提一下:
function turnPoint(a) {
var left = 0,
right = a.length - 1,
mid,
len = a.length;
while (left <= right) {
while (left <= right && a[left + 1] == a[left]) left++;
while (left <= right && a[right - 1] == a[right]) right--;
mid = (left + right) / 2;
if (mid > 0 && mid + 1 < len) {
if (a[mid - 1] < a[mid] && a[mid + 1] < a[mid])
return a[mid];
else if (a[mid - 1] < a[mid] && a[mid] < a[mid + 1])
left = mid + 1;
else if (a[mid - 1] > a[mid] && a[mid] > a[mid + 1])
right = mid - 1;
}
}
return -1;
}
console.log(turnPoint([1,2,3,4,5,4,3,2,1]));
console.log(turnPoint([1,1,1,1,1,2,1,1]));
console.log(turnPoint([1,2,1,1,1,1,1,1]));
h*********o
发帖数: 230
5
有dup就不work了吧

【在 c*****e 的大作中提到】
: 直接二分:
: left和right先skip掉相同的数,
: 然后left, right取mid,看mid的左[mid-1]右[mid+1]:
: 如果左右都小,则找到;
: 如果左小右大,则在非递减部分,更新left=mid+1
: 如果左大右小,则在非递增部分,更新right=mid-1
: 贴个js代码不知道有没有bug,有的话麻烦提一下:
: function turnPoint(a) {
: var left = 0,
: right = a.length - 1,

l*********d
发帖数: 78
6
如果有dup应该就没有log(n)解了吧。。
s********x
发帖数: 81
7
好像确实是没有, average case下, 肯定用binary search.
但是在worse case下, 是O(N). 一个特别长的数列, 所有元素都是1, 除了第二个元素
是2
left, mid, right
left < mid && mid < right, 点在mid和right之间
left < mid && mid = right, 两边都有可能
left < mid && mid > right, 两边都有可能
left = mid && mid < right, 点在mid和right之间
left = mid && mid = right, 两边都有可能
left = mid && mid > right, 两边都有可能
left > mid && mid < right, 不可能
left > mid && mid = right, 点在left和mid之间
left > mid && mid > right, 点在left和mid之间
z******g
发帖数: 271
8
应该询问面试官如果拐点处有dup该怎么算
w*****t
发帖数: 485
9
这个解法不错,思路是对的!
不过这个代码对一些边界没有处理:
比如只有一个元素时,left+1会越界
"if (mid > 0 && mid + 1 < len)", 如果这个条件不满足,会导致死循环

【在 c*****e 的大作中提到】
: 直接二分:
: left和right先skip掉相同的数,
: 然后left, right取mid,看mid的左[mid-1]右[mid+1]:
: 如果左右都小,则找到;
: 如果左小右大,则在非递减部分,更新left=mid+1
: 如果左大右小,则在非递增部分,更新right=mid-1
: 贴个js代码不知道有没有bug,有的话麻烦提一下:
: function turnPoint(a) {
: var left = 0,
: right = a.length - 1,

c*****e
发帖数: 67
10
嗯写得太快没写完整,只默认为输入是存在拐点的。
如果考虑上各种不存在拐点的情况:
1. 边界那里的确粗心了,应该是left+1<=right和left<=right-1
2. 加个判断避免死循环:
while (left + 1 <= right && a[left + 1] == a[left]) left++;
while (left <= right - 1 && a[right - 1] == a[right]) right--;
if (left == right) return -1;

【在 w*****t 的大作中提到】
: 这个解法不错,思路是对的!
: 不过这个代码对一些边界没有处理:
: 比如只有一个元素时,left+1会越界
: "if (mid > 0 && mid + 1 < len)", 如果这个条件不满足,会导致死循环

1 (共1页)
进入JobHunting版参与讨论
相关主题
请教大家一个算法的面试题目求函数的极值那题的解法?
问个snapchat的面经题 二分检索的关于最长递增子序列的问题。
问uber的一道题F家onsite悲剧了,求refer
问道题你们刷题都刷傻了, 那么简单的题目都做错
一个题search in a rotated array
G家phone interview经验,攒人品[算法]二分搜索变体
找个先增后减的数组里的数。find median for k sorted arrays
问一道题(5)谁给个数组分段题二分法的总结啊?
相关话题的讨论汇总
话题: mid话题: left话题: right话题: turnpoint话题: 拐点