求中位数与LeetCode462:最少移动次数使数组元素相等 II

求中位数

中位数:也就是选取中间的数,是一种衡量集中趋势的方法。
例1:找出这组数据:23、29、20、32、23、21、33、25 的中位数。
解:首先将该组数据进行排列(这里按从小到大的顺序),得到:
20、21、23、23、25、29、32、33
因为该组数据一共由8个数据组成,即n为偶数,故按中位数的计算方法,得到中位数 = 23 + 25 2 = 24 =\frac{23+25}{2}=24 =223+25=24 ,即第四个数和第五个数的平均数。

解法一:普通法

def get_median(data):
        data = sorted(data)
        size = len(data)
        if size % 2 == 0:   # 判断列表长度为偶数
            median = (data[size//2]+data[size//2-1])/2
            data[0] = median
        if size % 2 == 1:   # 判断列表长度为奇数
            median = data[(size-1)//2]
            data[0] = median
        return data[0]

解法二:最佳

这个解决方法非常巧妙,它利用了取反数和为1的特性,通过列表负索引来获得列表中位数。

return (data[half] + data[~half]) / 2 的解释:

排序后得到序列[1,2,3,4,5,6],其列表长度为偶数,中位数由列表中间两位元素3(索引为2),4(索引为3)决定。而元素4的负索引为-3,正好是索引2的取反数。

排序后得到序列[1,2,3,4,5],其列表长度为奇数,中位数由列表中间元素3(索引为2,负索引为-3)决定。仍然符合代码。

def get_median(data):
         data.sort()
         half = len(data) // 2
         return (data[half] + data[~half]) / 2 # 注意这里是取反操作符~,其结果等效于(-half-1)

==注意这里是取反操作符~,其结果等效于(-half-1)==因为从左往右是从0开始,从右往左是从1开始

注释:关于取反操作的解释

按位取反运算符,用来对一个二进制数按位取反,即将0变1,将1变0,按理说十进制的5(0000 0101)按位取反应该为(1111 1010)十进制250,但是在Python中运算结果并非如此,结果如下:

>>> ~-6
5

计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。

正整数的补码是其二进制表示,与原码相同 。
负整数的补码,将其对应正数二进制表示所有位取反(包括符号位,0110)后加1

Python按位取反运算:

>>> ~-6
5

-6的补码是+6(0000 0110)取反后再+1,为(1111 1001)+(0000 0001)=(1111 1010),
,也就是计算机中-6是用(1111 1010)来存储的,(1111 1010) 按位取反得到(0000 0101)这就是答案5

LeetCode462:最少移动次数使数组元素相等 II

问题描述

给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。

例如:

输入:
[1,2,3]

输出:
2

说明:
只有两个动作是必要的(记得每一步仅可使其中一个元素加1或减1):

[1,2,3] => [2,2,3] => [2,2,2]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii

解法

class Solution:
    def minMoves2(self, nums: List[int]) -> int:
        sorted_num = sorted(nums)
        temp = len(sorted_num) // 2
        mid = (sorted_num[temp] + sorted_num[-(temp+1)]) / 2

        count = 0
        for i in nums:
            count += abs(i-mid)
        return int(count)

执行用时 :168 ms, 在所有 Python3 提交中击败了5.38%的用户
内存消耗 :15 MB, 在所有 Python3 提交中击败了5.80%的用户

参考文献

Python的按位取反运算符~
Python面试题 —— 获取列表中位数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值