关注微信公众号“酸痛鱼”,解锁更多精彩文件,获得最新的内容更新。
本文中所涉及的代码,在未特殊声明的情况下,都是基于Python3程序设计语言编写的。
建议您在PC浏览器中阅读本文。
如果您未掌握知识提要中的内容,建议您先掌握这些内容之后再阅读本文。
知识提要
1、函数定义
2、列表、访问列表元素
3、比较函数cmp
4、内置函数len和range
0
问题描述
实现一个函数,判定传入的数组A是否单调。如果单调,返回True,否则返回False。
对一个整型数组,如果它是升序排序或者降序排序的,那么它是单调的。也是就是说对于数组A,给定任意两个下标i和j,且i<=j:
如果A[i]<=A[j],那么A是升序排序的,也就是单调递增的;
如果A[i]>=A[j],那么A是降序排序的,也就是单调递减的。
1
比较函数
比较函数的功能是,给定两个值a和b,判定它们的大小。如果ab,返回1。
Python2的内置函数cmp就是实现这样的功能。Python3中并没有这个内置函数,我们需要自己实现。
def cmp(a, b):
if a < b: return -1
if a == b: return 0
return 1
为了表述方便,我们将cmp(a, b)的返回值,称为a和b的比值,或者单调方向。
2
解题思路
如果一个数组单调,那么对于数组中所有相邻的两个数的比值,要么总是大于等于0,要么总是小于等于0。利用这个属性,我们可以不停地比较相邻的两个数,并记录第一次比值不为零的情况。之后,如果遇到相邻两个数比值不为零的情况,而且与第一次记录的比值不同,则数组不单调。如果直到数组的最后两个相邻的数,比值一直为0或者一直与第一次记录相同,则数组单调。
def cmp(a, b):
if a < b: return -1
if a == b: return 0
return 1
def monotonic(array):
size = len(array)
# 记录单调方向,-1为递减,1为递增
global_dir = None
for i in range(size - 1):
cur_dir = cmp(array[i], array[i + 1])
if cur_dir == 0:
# 如果两个相邻的数相等,则忽略
continue
elif global_dir is None:
# 第一次不相等的两个数的单调方向,就是整个数组期望的单调方向
global_dir = cur_dir
elif global_dir != cur_dir:
# 出现与期望的单调方向不同的情况,则该数组不单调
return False
return True
3
优化
如果一个数组单调,那么,第一个数字和最后一个数字的单调方向,就是整个数组的单调方向。利用这个特点,我们可以在一开始,就假设数组A的单调方向为cmp(A[0], A[-1])。
值得一提的是,如果单调数组出现cmp(A[0], A[-1])比值为0的情况,则说明整个数组的每一个元素的值都是相等的。
def cmp(m, n):
if m < n: return -1
if m == n: return 0
return 1
def monotonic(array):
size = len(array)
if size <= 1: return True
# 第一个数和最后一个数的单调方向,就是整个数组的单调方向
global_dir = cmp(array[0], array[-1])
for i in range(size - 1):
cur_dir = cmp(array[i], array[i + 1])
if cur_dir != 0 and cur_dir != global_dir:
return False
return True
4
再优化
对于单调数组A,如果A[0] <= A[-1],那么A[i]<=A[i+1];如果A[0]>=A[-1],那么A[i]>=A[i+1]。利用这个特性,我们可以不使用cmp函数。我们只需要记录A[0] <= A[-1]的值G,并保证A[i]==A[i+1]或者A[i]
def monotonic(array):
size = len(array)
if size <= 1: return True
# 第一个数和最后一个数的方向,就是整个数组的单调方向
global_dir = array[0] <= array[-1]
for i in range(size - 1):
if array[i] == array[i + 1]:
continue
elif (array[i] < array[i + 1]) != global_dir:
return False
return True微信扫码关注我哦
酸痛鱼,与你分享快乐的代码