在东边 发表于 2020-6-7 14:48:11

对列表按照元素出现次数升序排序,要求空间复杂度为O(1)

本帖最后由 在东边 于 2020-6-7 15:39 编辑

有一个列表,假设为

nums =

按照元素出现次数升序排序,排序结果应该是



可以在空间复杂度为 O(1) 的前提下,实现这样的排序算法吗?

下面这两种方法是不可行的:

1.

nums.sort(key=nums.count)

执行上面代码后,发现 nums 还是原来的 nums

看了下 Python 官方文档关于 list.sort 的介绍

里面提到

CPython implementation detail: 在一个列表被排序期间,尝试改变甚至进行检测也会造成未定义的影响。 Python 的 C 实现会在排序期间将列表显示为空,如果发现列表在排序期间被改变将会引发 ValueError。

排序期间列表显示为空,所以在对 nums 调用 sort 方法时,nums 始终为 [],nums.count 始终返回 0,因此 nums 未发生改变

2.

nums.sort(key=nums[:].count)

上面这行代码可以达到按元素出现次数排序,但由于使用列表的切片 nums[:],创建了一份拷贝,空间复杂度不是 O(1)

Twilight6 发表于 2020-6-7 14:58:12

本帖最后由 Twilight6 于 2020-6-7 15:07 编辑

{:10_245:}

这样的空间复杂度算 O(1) 吧
nums =
nums.sort()
nums.reverse()

永恒的蓝色梦想 发表于 2020-6-7 15:12:05

基础nums.sort(reverse=True)

Twilight6 发表于 2020-6-7 15:17:38

永恒的蓝色梦想 发表于 2020-6-7 15:12
基础

学到了{:10_256:},我居然不知道还有这种用法

永恒的蓝色梦想 发表于 2020-6-7 15:19:02

Twilight6 发表于 2020-6-7 15:17
学到了,我居然不知道还有这种用法

{:10_277:}

赚小钱 发表于 2020-6-7 15:19:14

Twilight6 发表于 2020-6-7 14:58
这样的空间复杂度算 O(1) 吧

要看 sort 内部的实现。
基本上,时间复杂度在 O(nlogn) 的排序算法,空间复杂度都是不 O(1)。
而时间复杂度在 O(n^2) 的排序算法,空间复杂度是 O(1)。

在东边 发表于 2020-6-7 15:20:12

永恒的蓝色梦想 发表于 2020-6-7 15:12
基础

看来这个 nums = 不太恰当{:10_277:}

如果是下面这样呢

nums =

nums.sort(revere=True)

排完后,是

可是按元素出现次数排序,应该是

Twilight6 发表于 2020-6-7 15:28:35

。。。才看见楼主说的是按出现次数排序

永恒的蓝色梦想 发表于 2020-6-7 15:31:15

在东边 发表于 2020-6-7 15:20
看来这个 nums = 不太恰当

如果是下面这样呢


这个空间复杂度很低了{:10_277:}from collections import Counter
nums.sort(key=Counter(nums).__getitem__)

在东边 发表于 2020-6-7 15:37:13

永恒的蓝色梦想 发表于 2020-6-7 15:31
这个空间复杂度很低了

假设这个列表长度为 n,里面每个元素都只出现 1 次(最坏情况)

那么使用 Counter 实例化后的对象长度也为 n

空间复杂度就是 O(n)

其实,我觉得吧,只要引入了新的容器对象,不管是 list,Counter 还是其他

空间复杂度都不可能是 O(1) 了

Stubborn 发表于 2020-6-7 15:42:43

时间复杂度在 O(n^2) 的排序算法,空间复杂度是 O(1)。

可以很简单的实现啊

在东边 发表于 2020-6-7 15:50:44

Stubborn 发表于 2020-6-7 15:42
时间复杂度在 O(n^2) 的排序算法,空间复杂度是 O(1)。

可以很简单的实现啊

我是要按照元素出现次数排序,不是要按照元素大小排序

要想知道每个元素出现多少次,那至少得遍历一遍,然后存在某个容器里,再根据次数排序吧

既然产生了新的容器,空间复杂度就不是 O(1) 了

或者是有什么我没想到的方法吧。。。{:10_266:}

永恒的蓝色梦想 发表于 2020-6-7 15:51:33

{:10_277:}效率炸裂def sort(list):
    flag=True
    robj=range(1,len(list))
   
    while flag:
      flag=False

      for i in robj:
            if list.count(list)<list.count(list):
                list,list=list,list
                flag=True

赚小钱 发表于 2020-6-7 15:56:14

无法实现
按照频率排序原列表,至少需要三步,
1. 统计每个元素的频率
2. 对频率排序
3. 将频率的顺序,映射到实际元素

所以,空间复杂度至少为 O(n),时间复杂度为 O(nlogn)

靳子轩 发表于 2020-6-7 16:40:05

我只会这两种方法,应该是O(1)

Stubborn 发表于 2020-6-7 16:56:31

本帖最后由 Stubborn 于 2020-6-7 17:11 编辑

假设一个问题,

nums =

这个数组,第一个排序后,不管大小位置,我只把相同的排列到一起。产生如下序列

nums =

出现次数升序排序,知道,最低是出现一次,换而言之,不用管其他的顺序

我扫描数组,把出现一次的,list.insert(index=0, obj),

记录已经处理的长度len1,处理完一个+1.和一个“阶层”长度(default=0,当一个处理完,开始处理2次,更新为第一次出理完的长度)《处理的长度,用于记录下一‘’层;次该插入的位置,以及程序进度》《“阶层”的长度用于插入的位置》





Python_Aaron 发表于 2020-6-7 18:21:52

新手看不懂,什么是空间复杂度?{:10_269:}

Stubborn 发表于 2020-6-7 19:48:44

挣个10鱼币,不容易啊!{:10_295:}

本帖最后由 Stubborn 于 2020-6-7 20:20 编辑

{:10_272:}
def SorteTimeComplexityOne(Array):
    length = len(Array)
    idx = 2

    # TODO 数组排序,一样的放在一起。
    while length > idx:
      val = Array
      val_idx = Array.index(val)

      if val_idx < idx:
            del Array
            Array.insert(val_idx, val)

      idx += 1

    # TODO {
    #    Array:
    #    success : 已经处理完的元素长度
    #    task : 任务长度
    #    insert_idx : 插入位置
    #    idxl : 左侧索引
    #    idxr : 右侧索引
    #}
    success = 0
    insert_idx=0
    task = 1
    idxl = 0
    idxr = 1

    while length > success:

      if idxr < length and Array == Array:
            idxr += 1
      else:
            if task == idxr - idxl:

                while idxr - idxl:
                  val = Array
                  del Array
                  Array.insert(insert_idx, val)
                  idxl += 1
                  success += 1
            else:
                idxl = idxr

            if idxl >= length:
                idxl= idxr= insert_idx= success
                task += 1

    print(Array)

v.ki 发表于 2020-6-7 19:56:22

看不懂{:10_277:}

Stubborn 发表于 2020-6-7 19:56:24

赚小钱 发表于 2020-6-7 15:56
无法实现
按照频率排序原列表,至少需要三步,
1. 统计每个元素的频率


瞅瞅18楼的,时间,空间复杂度是多少{:10_262:}
页: [1] 2 3 4
查看完整版本: 对列表按照元素出现次数升序排序,要求空间复杂度为O(1)