偶然机会,在codewars上面开始做题,遇到一道有意思的题目,记录一下:
题目是这样的:
In this kata, you will write a function that returns the positions and the values of the "peaks" (or local maxima) of a numeric array.
For example, the array arr = [0, 1, 2, 5, 1, 0]
has a peak at position 3
with a value of 5
(since arr[3]
equals 5
).
The output will be returned as an object with two properties: pos and peaks. Both of these properties should be arrays. If there is no peak in the given array, then the output should be {pos: [], peaks: []}
.
Example: pickPeaks([3, 2, 3, 6, 4, 1, 2, 3, 2, 1, 2, 3])
should return {pos: [3, 7], peaks: [6, 3]}
(or equivalent in other languages)
All input arrays will be valid integer arrays (although it could still be empty), so you won't need to validate the input.
The first and last elements of the array will not be considered as peaks (in the context of a mathematical function, we don't know what is after and before and therefore, we don't know if it is a peak or not).
Also, beware of plateaus !!! [1, 2, 2, 2, 1]
has a peak while [1, 2, 2, 2, 3]
does not. In case of a plateau-peak, please only return the position and value of the beginning of the plateau. For example: pickPeaks([1, 2, 2, 2, 1])
returns {pos: [1], peaks: [2]}
(or equivalent in other languages)
大致意思就是说:给你一个数组,首尾的数字不算,找到波峰及其位置并返回,要求返回的结果是一个对象,{pos: [], peaks: []},前面pos中放波峰对应的位置,后面放波峰的值。
例如: pickPeaks([3, 2, 3, 6, 4, 1, 2, 3, 2, 1, 2, 3])
应该返回:{pos: [3, 7], peaks: [6, 3]}
。
但是,需要注意:像[1, 2, 2, 2, 1]
就应该返回波峰是第一个2及其位置,但是 [1, 2, 2, 2, 3]
就没有,前面的情况它们称之为缓波峰。
我的解法很啰嗦,费了一番功夫:
![](https://i-blog.csdnimg.cn/blog_migrate/29d0e8b6676c8a7f250ebe53b531d250.png)
我的代码是,循环比较,某一项如果大于前一项,且大于后一项直接push,如果大于前一项且等于后一项,放进临时变量,循环时检查临时变量,如果有值证明是缓坡,如果上缓坡之后值一直相等,就一直往后走,直到下坡,或者又上坡,下坡时,把记录的临时变量推入结果集中,如果继续上坡,则将临时变量清空。
然后测试、通过、提交之后,查看高手答案,有一个答案网友满意达到了60几个,然后看了一下,惊着了。。。
他的代码如下:
我天,如此简练,然后研究一下,发现他直接用所谓的数学上的斜率的概念,斜率为正就是上坡,斜率为负即为下坡,斜率为0为横线,不上不下。
第一行map处理极为巧妙,利用math.sign来标记正负,然后*i,一并记下当时的index,然后过滤掉为0的数值,相等的值并没有用(我的垃圾代码为考虑这个还颇费了一些功夫),
然后选择前一项大于0且后一项小于0的值,其实就是原始数组的index组合,然后又一个map搞定。摩拜大佬!!!