求數(shù)組有序后相鄰元素的最大差值,時(shí)間復(fù)雜度:O(n)

問(wèn)題描述:
給定一個(gè)數(shù)組,求有序后相鄰兩個(gè)數(shù)的最大差值,要求時(shí)間復(fù)雜度為O(n)
并且不能用非基于比較的排序算法

解決思路
我們使用桶排序的思想,但是不對(duì)數(shù)組進(jìn)行排序操作
因?yàn)槲覀冎恍枰@取當(dāng)前數(shù)組元素所在桶的序號(hào),并不是真實(shí)地將元素插入某個(gè)桶中

下面只是模擬的過(guò)程:

  1. 數(shù)組 a 中有 n 個(gè)元素,則準(zhǔn)備 n+1 個(gè)桶,將數(shù)組的最小值放入 0 號(hào)桶,最大值放入 n 號(hào)桶
  2. 將數(shù)組剩余的 n-2 個(gè)元素按順序均勻放入剩余的 n-1 個(gè)桶中(每個(gè)桶中的元素是有序的),則必有一個(gè)空桶,
    因此要求的最大差值一定不會(huì)來(lái)自同一個(gè)桶的相鄰元素之差
  3. 最大差值一定是相鄰兩個(gè)桶的后一個(gè)桶中最小值與前一個(gè)桶中最大值之差,相鄰兩個(gè)桶中間可能會(huì)有空桶

max_differ_sorted.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2018-06-16 23:09:23

"""
給定一個(gè)數(shù)組,求排序之后相鄰兩個(gè)數(shù)的最大差值,要求時(shí)間復(fù)雜度為O(n)
并且不能用非基于比較的排序算法

解決思路
我們使用桶排序的思想,但是不對(duì)數(shù)組進(jìn)行排序操作
因?yàn)槲覀冎恍枰@取當(dāng)前數(shù)組元素所在桶的序號(hào),并不是真實(shí)地將元素插入某個(gè)桶中
下面只是模擬的過(guò)程:
1.數(shù)組 a 中有 n 個(gè)元素,則準(zhǔn)備 n+1 個(gè)桶,將數(shù)組的最小值放入 0 號(hào)桶,最大值放入 n 號(hào)桶
2.將數(shù)組剩余的 n-2 個(gè)元素按順序均勻放入剩余的 n-1 個(gè)桶中,則必有一個(gè)空桶,
  因此要求的最大差值一定不會(huì)來(lái)自同一個(gè)桶的相鄰元素之差
3.最大差值一定是相鄰兩個(gè)桶的后一個(gè)桶中最小值與前一個(gè)桶中最大值之差,相鄰兩個(gè)桶中間可能會(huì)有空桶
"""

from util import Util
from sort import Sort

def max_differ_sorted(a):
    """
    時(shí)間復(fù)雜度:O(n)
    """
    n = len(a)
    if n < 2:
        return 0

    _max = max(a)   #獲取最大值
    _min = min(a)   #獲取最小值
    # print(_min)
    # print(_max)
    if _min == _max:    #如果最大值等于最小值,則a中所有的數(shù)相等
        return 0

    # 準(zhǔn)備三個(gè)長(zhǎng)度為n+1的列表
    # hasNum記錄每個(gè)桶中是否有數(shù)字
    # mins記錄每個(gè)桶中的最小值
    # maxs記錄每個(gè)桶中的最大值
    hasNum = [False] * (n+1)
    mins = [None] * (n+1)
    maxs = [None] * (n+1)
    id = 0
    for i in range(0, n):
        id = bucket(a[i], n, _min, _max)    # 獲得當(dāng)前元素屬于哪個(gè)桶
        mins[id] = min(a[i], mins[id]) if hasNum[id] else a[i]
        maxs[id] = max(a[i], maxs[id]) if hasNum[id] else a[i]
        hasNum[id] = True

    # max_differ等于后一個(gè)桶最小值與前一個(gè)桶最大值之差的最大值
    res = 0
    lastMax = maxs[0]
    for j in range(1, n+1):
        if hasNum[j]:
            res = max(res, mins[j] - lastMax)
            lastMax = maxs[j]

    return res
    pass

def max_differ_sorted_std(a):
    """
    最直接的方法,先排序,再求相鄰的最大差值
    時(shí)間復(fù)雜度:平均O(nlogn) > O(n)
    """
    n = len(a)
    if n < 2:
        return 0

    Sort.quick_sort(a)
    res = 0
    for i in range(n-1):
        res = max(res, a[i+1] - a[i])
        pass
    return res
    pass

def bucket(x, n, min, max):
    """
    x:待放入桶中的數(shù)
    n:數(shù)組的長(zhǎng)度
    min:數(shù)組元素最小值
    max:數(shù)組元素最大值
    """
    return (x - min) * n // (max - min)
    pass

def test():
    a = Util.gen_randint_list()

    max_differ = max_differ_sorted(a)
    print(a)
    max_differ_std = max_differ_sorted_std(a)
    print(a)

    print('test: ', end = '')
    print(max_differ)
    print('std:  ', end = '')
    print(max_differ_std)

    if max_differ_std == max_differ:
        print('true')
    else:
        print('false')
    pass

if __name__ == '__main__':
    for x in range(10):
        test()
        pass

util.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2018-06-11 22:58:30

import random

class Util(object):
    """
    工具類
    """
    def gen_randint_list(n = 5, min = 0, max = 10):
        """
        生成一個(gè)隨機(jī)int型列表
        """
        if n < 1 or min > max:
            return []

        rand_list = []
        for i in range(n):
            rand_list.append(random.randint(min, max))
            
        return rand_list
        pass

測(cè)試結(jié)果

max_differ_sorted.PNG

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 該文章總結(jié)自牛課網(wǎng)的在線算法課程(https://www.nowcoder.com/) 經(jīng)典排序算法就是前面講那幾...
    鍋與盆閱讀 7,841評(píng)論 6 14
  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,299評(píng)論 0 52
  • 概述:排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,823評(píng)論 0 15
  • A: 布魯姆說(shuō):在某種生命里,思想就是唯一真實(shí)的事件。也許語(yǔ)言文字是承載個(gè)體生命中思想觀念真實(shí)性事件的必要的載體....
    玩哲閱讀 4,660評(píng)論 11 67
  • 昨天寫那篇《十全十美好嗎》的時(shí)候,偶然間在網(wǎng)上看到這樣一段話,它是一位網(wǎng)友用來(lái)解釋十全十美真正含義的。非常深刻,非...
    云淡風(fēng)輕任平生閱讀 741評(píng)論 0 1

友情鏈接更多精彩內(nèi)容