目录
摘要:
本文主要涉及数据结构中的排序算法,以及Python中的除法问题,保留特定小数位数的问题
背景:
leetcode第 1491 题:去掉最低工资和最高工资后的工资平均值
问题描述:
给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资。
请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。
示例 1:
输入:salary = [4000,3000,1000,2000]
输出:2500.00000
解释:最低工资和最高工资分别是 1000 和 4000 。
去掉最低工资和最高工资以后的平均工资是 (2000+3000)/2= 2500
示例 2:
输入:salary = [1000,2000,3000]
输出:2000.00000
解释:最低工资和最高工资分别是 1000 和 3000 。
去掉最低工资和最高工资以后的平均工资是 (2000)/1= 2000
示例 3:
输入:salary = [6000,5000,4000,3000,2000,1000]
输出:3500.00000
示例 4:
输入:salary = [8000,9000,2000,3000,6000,1000]
输出:4750.00000
提示:
3 <= salary.length <= 100
10^3 <= salary[i] <= 10^6
salary[i] 是唯一的。
与真实值误差在 10^-5 以内的结果都将视为正确答案。
解答方案
方案1:采用Python自带的排序函数sort(),将数据salary排序后除去第一位及最后一位,将其余元素累加再求平均,代码如下:
class Solution(object):
def average(self, salary):
"""
:type salary: List[int]
:rtype: float
"""
salary.sort()
res=0.0
for i in range(1,len(salary)-1):
res+=salary[i]
return res/(len(salary)-2)
方案2:可以采用一次冒泡算法将最大值冒泡到最后,同理将最小值冒泡到最前面,然后将数据salary排序后除去第一位及最后一位,将其余元素累加再求平均,代码如下:
class Solution(object):
def average(self, salary):
"""
:type salary: List[int]
:rtype: float
"""
for i in range(len(salary)-1):
if salary[i]>salary[i+1]:
p=salary[i]
salary[i]=salary[i+1]
salary[i+1]=p
j=len(salary)-1
while j>0:
if salary[j]<salary[j-1]:
q=salary[j]
salary[j]=salary[j-1]
salary[j-1]=q
j-=1
summer=0
for k in range(1,len(salary)-1):
summer+=salary[k]
return round(float(summer)/(len(salary)-2),5)
答案解析:
1)方案1和2用时对比如下:可以发现方案1用时比方案2多,原因在于方案1将数组全部排序,而方案2只求了最大值和最小值,所以用时少。(冒泡排序算法还是经典)
2)方案2中采用了Python除法保留相关位数的问题,详解如下:
Python除法保留两位小数点(三种方法实现)
- 方法1
- 方法2
- 方法3
- 方法1
a = 1
b = 3
print(round(a/b,2))
- 方法2
a = 1
b = 3
print(format(float(a)/float(b), '.2f'))
- 方法3
a = 1
b = 3
print('%.2f'%(a/b))
3)关于Python整除和非整除问题详解如下:
从python2.2开始,便有两种除法运算符:"/"、"//"。两者最大区别在:
- python2.2前的版本和python2.2以后3.0以前的版本的默认情况下,"/"所做的除法是以一种两个数或者多个数出现一个浮点数结果就以浮点数的形式表示,即float除法
- "//"所做的除法则不相同,"//"不管两者出现任何数,都以整除结果为准,不对小数部分进行处理,直接抛弃,也就是整除法
以下是笔者在编译器测试的数据,测试的版本是python2.7
关于"/":
-
>>> 3/2
-
1
-
>>> 3/2.0
-
1.5
-
>>> 3.0/2
-
1.5
-
>>> 10/3.0
-
3.3333333333333335
-
由以上的例子我们可得出,只要除数中有一个数是浮点数,那么得到的结果也是浮点数
以下是关于"//":
-
>>> 3//2
-
1
-
>>> 3//2.0
-
1.0
-
>>> 3.0//2
-
1.0
-
>>> 3.0//2.0
-
1.0
-
由以上的例子,我们可以看出,两个整型相除,得到的还是整型,但是。如果一个浮点数除以一个非浮点数得到的还会是一个浮点数,但是,计算的结果却是忽略小数部分,运算的结果类似两个整型相除,但是得到一个浮点数。另外"//"对于两个浮点数也是不例外的。
如何让"/"和"//"进行分工
在默认情况下,这两种运算符有很大的重叠地方,比如,当两个数都是整数的时候,两者的运算结果是没有区别的。如果想在python中让这两种有一个明确的分工。即"/"可以用于float除法,"//"用于整除法,我们可以在程序开始的时候做以下声明:
-
from __future__ import division
-
声明后测试的结果(以下测试的版本是python2.7)
-
>>> from __future__ import division
-
>>> 3/2
-
1.5
-
>>> 3.0/2
-
1.5
-
>>> 3/2.0
-
1.5
-
>>> 3.0/2.0
-
1.5
-
>>> 3//2
-
1
-
>>> 3.0//2
-
1.0
-
>>> 3.0//2.0
-
1.0
-
>>> 3//2.0
-
1.0
-
>>> -11/2
-
-5.5
-
以上,我们可以知道,做这个声明以后,"/"进行的将是float除法而不是整除法。
还需要注意的是,在pyhton3中,"/"表示的就是float除,不需要再引入模块,就算分子分母都是int,返回的也将是浮点数