Leetcode bucket分組桶排序

2021-10-10 14:01:42 字數 1985 閱讀 6971

通排序是初始化一定數量的桶arr[n]= 對於數i 填入arr[i]即可(arr[i]++) 那麼最後遍歷arr即可,適用於範圍較小的排序,複雜度為o(n)

題目描述給定乙個整形陣列arr,返回排序後相鄰兩數的最大差值

arr = [9, 3, 1, 10]。如果排序,結果為[1, 3, 9, 10],9和3的差為最大差值,故返回6。

arr = [5, 5, 5, 5]。返回0。

[要求]

時間複雜度為o(n),空間複雜度為o(n)

思路

本題求排序後相鄰兩個數的最大差值,對於n個數字,其大小範圍為:【min,max】 那麼可以有推論:

最大差值》=width/n-1 取到最小值時,恰好所有數字之間間隔相等

本題的通排序做法是:

初始化一定數量的桶,每個桶的表示範圍為width/n-1 總共n+1個桶,那麼每個數字可以對映到不同的桶

總共數字的範圍是:min=>max 而總共兩兩之間的區間個數為 n-1 那麼直接設定桶的數量為n

每個桶的對映範圍大小為:width/n-1 那麼最大差值的兩個數一定分布在不同的桶。*

具體到每個桶,其只需要記錄所在桶的數字中最大值,最小值即可。因為最大差值由於分布在不同的桶:

當前桶的最小值-減去上乙個桶的最大值(過濾掉沒有數值的桶) 遍歷一遍桶即可找到最大差值

#include

#include

#include

using

namespace std;

intmain()

//設定n個桶 容易知道 每個桶的對映範圍大小為 (_max-_min)/n-1

// =>最小的數在第0個桶 最大的數在第n-1個桶

vector<

bool

>

hasnum

(n,false);

vector<

int>

min_b

(n);

vector<

int>

max_b

(n);

// max[i]=k 表示第i個桶的最大值為k

int width=_max-_min;

//數的範圍區間

float bucket_width=

float

(width)

/(n-1)

;//乙個桶的表示範圍

if(width==0)

for(

int i=

0;i)//可以證明 最大差值一定大於或等於 width/n-1(恰好兩兩之間相等)

//而乙個桶設定的表示的數範圍為: width/n-1 那麼最大差值的兩個數一定分布在不同的桶

int res=0;

int i=0;

int j=1;

while

(jcout<

}

本題關鍵點,桶的表示範圍小於超過最大的兩數之差的最小值,否則可能最大差值在乙個桶中。這樣可以確保最大的兩數之差的兩個數分布在不同的桶。

另外,本題桶大小初始化為width/n-1 注意為float型別簡化計算,否則int可能需要考慮桶的數量是否足夠。 若採取int型別 int bucket_width=(max-min)/(n-1)+1 即桶的範圍總是:平均的範圍大小(int)+1

分目錄 分埠

分目錄站點 意義 可能有多個cms或框架組成,對於滲透 相當於滲透目標是多個 入侵分目錄下的站點 主站也跟著被入侵 主站與分目錄站點搭建的cms可能不同 找到乙個有漏洞可利用的cms即可對 進行入侵 分埠站點 同理 www.com www.com 8080 www.com 8888 意義 可能有多個...

分糖果 差分約束

description 幼兒園裡有n 個小朋友,lxhgww 老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww 需要滿足小朋友們的 k個要求。幼兒園的糖果總是有限的,l...

分巧克力 (二分)

問題描述 兒童節那天有k位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友們。小明一共有n塊巧克力,其中第i塊是hi x wi的方格組成的長方形。為了公平起見,小明需要從這 n 塊巧克力中切出k塊巧克力分給小朋友們。切出的巧克力需要滿足 1.形狀是正方形,邊長是整數 2.大小相同 例如一塊6x5...