c - 检查数组是否是单峰的
问题描述
一个整数数组是单峰的,如果:
一开始是严格增加的;之后它是恒定的;在那之后,它是严格下降的。第一个块(增加)和最后一个块(减少)可能不存在。允许这两个块都不存在。
例如下面三个数组是单峰的:[5, 7, 11, 11, 2, 1], [4, 4, 2], [7],但是下面三个不是单峰的:[5, 5, 6 , 6, 1], [1, 2, 1, 2], [4, 5, 5, 6]。
编写一个 C 程序来检查一个数组是否是单峰的。限制:函数应该按 n 的顺序运行。数组元素之间的比较操作不应超过 n-1 次。
我可以使用 3 个 while 循环(非嵌套)并检查数组的 3 个部分,如果第 1 部分增加然后第 2 部分是恒定的并且第 3 部分减少吗?
解决方案
虽然可以为单峰曲线中的每个可能阶段在三个循环中对此进行编码,但这种“有状态”算法并不是特别数学。请注意,通过将状态保留在变量中而不是代码控制流中,可以在单个循环中实现等效的有状态算法。
它可能在数学上更稳健(或至少证明对这种曲线的数学理解),并且更简单地测试单个公分母 - 即对于单峰曲线上的每个点都成立的共同关系,但是不适用于任何非单峰曲线。通过这种方式,您可以在单个循环中执行算术测试,而不是通过控制流或状态转换。
在这种情况下,这个单一的公分母 - 在数学上定义曲线的一个是: 曲线梯度的符号是单调递减的。
Signum 是一个函数,使得 signum(a) 是:
- 0 如果 a == 0,
- 1 如果 a > 0,
- -1 如果 a < 0
虽然单调递减意味着该值要么下降要么保持不变,但永远不会上升——它都是下坡或高原。
任何一点的梯度只是 d[n+1] - d[n]。所以循环从另一个元素中减去一个元素,确定符号,并将其与前一个符号进行比较。如果符号增加,则曲线不是单峰的。那就是它只能上升,只能平坦或只能下降,或者它可以上升和下降,但永远不会再次上升,具有任意数量的水平高原。
请注意,此解决方案适用于单峰曲线的数学定义;您问题中的定义有些模棱两可,似乎不允许出现多个高原。也就是说,它允许:
_________
/ \
/ \
/ \
但不包括例如:
___
/ \
___/ \____
/ \
然而,我认为第二个显然是单峰的。
来自:https ://en.wikipedia.org/wiki/Unimodality :
最后一部分是关键 -零不算作符号更改。然而,无论这种微妙之处如何,它都适用于您的所有测试用例。
推荐阅读
- c# - 如何在小分辨率上显示多余的文本
- mysql - MySQL 触发函数(在 3 个不同的表之间)
- c - 访问冲突 strcpy
- javascript - 而不是转到不同的页面,而是以模式打开页面
- java - 如何将 ScrollPane 的高度绑定到 BorderPane 的底部?
- filter - 具有多个(复合)键的 DGET 返回 #NUM!错误
- javascript - 使用 javascript 读取/写入数据的最佳方法是什么?
- linux - 如何从 gitbash 生成多个 SSH 公钥并在 Windows 机器上配置这些公钥?
- mongodb - 如何在 mongodb 中使用 $lookup $let 变量?
- wordpress - 为 Wordpress 网站开发或插件建议