本文現轉載他人文章,後續會進行詳細講解。
1 無序數組 排序後 最大間隔
原題:給你n個任意整數,求排序後相鄰兩個數之間的最大差值,這裏n可能有10^5,整數爲任意32位整型。要求求解算法的時間複雜度爲O(n)。
1.1 思路:不排序的桶排序
原文鏈接:https://blog.csdn.net/xindoo/article/details/52821167
回到題目, 首先說明一點,這題的大體思路就是桶排序,但是,不需要全部排序,只需要大體有序,其實就是每個桶內的數不需要有序,接下來我將解釋爲什麼桶內的數不需要排序。
n個任意的數,劃分到n個桶裏。首先第一種情況,如果恰好每個桶都只有一個數,劃分後不就恰好有序了嗎,有序這道題不就好解決了嗎! 另一種情況,在每個數數值範圍非常大的時候也是很常見的,就是數不會均勻的落到每個桶中,這題的主要難點也在這。
如何解決? 想想看,在任意一個桶內任何情況下任意倆數的最大差值是多少,最大不就是桶的大小減一嗎? 但是,在全局中肯定存在兩個桶,後面一個桶的最小值和前一個桶的最大值差值大於桶大小,且這兩個桶之間不存在其他有數存在的桶,即都是空桶。 換種牽線的說法,絕對存在bucket[j].min - bucket[i].max > bucket[i].size-1(j > i且 i和j之間無其他非空桶)。理解了這點,此題得解。
其實我們只需要遍歷次數組,找出最大最小值,然後安裝最大最小值,將其他數劃分到n個桶裏。然後求連續兩個非空桶i j的bucket[j].min - bucket[i].max的最大值即可。
想想看,因爲我們只需要用到每個桶的最大最小值,所以不需要在每個桶中保存所有的值,只需要最大最小值而已。
1.2 程序實現
原文鏈接:https://blog.csdn.net/u010601662/article/details/79271370
int maxGap(std::vector<int> &vecNum)
{
// 獲取最大值與最小值
int nMax = vecNum[0], nMin = vecNum[0];
for (int nIndex = 1; nIndex < vecNum.size(); nIndex++)
{
if (nMax < vecNum[nIndex])
{
nMax = vecNum[nIndex];
}
else if (nMin > vecNum[nIndex])
{
nMin = vecNum[nIndex];
}
}
// 桶的個數
int nBucketNum = vecNum.size() + 1;
// 每個桶的區間長度
int nBucketLength = (nMax - nMin) / vecNum.size();
// 記錄桶的最小值
std::vector<int> vecBucketMin(nBucketNum, INT_MAX);
// 記錄桶的最大值
std::vector<int> vecBucketMax(nBucketNum, INT_MIN);
// 獲取每個桶內的最小和最大值
for (int nIndex = 0; nIndex < vecNum.size(); nIndex++)
{
// 映射到某一個桶
int nBucketIndex = (vecNum[nIndex] - nMin) / nBucketLength;
// 記錄桶的最大和最小值
if (vecBucketMax[nBucketIndex] < vecNum[nIndex])
{
vecBucketMax[nBucketIndex] = vecNum[nIndex];
}
if (vecBucketMin[nBucketIndex] > vecNum[nIndex])
{
vecBucketMin[nBucketIndex] = vecNum[nIndex];
}
}
// 計算每一個空桶右端非空桶中的最小值,與空桶左端非空桶的最大值的差
int nMaxGap = 0;
int nPreMax = vecBucketMax[0];
bool nEmptyBucket = false;
for (int nBucketIndex = 1; nBucketIndex < nBucketNum; nBucketIndex++)
{
if (vecBucketMin[nBucketIndex] != INT_MAX)
{
// 非空桶
if (nEmptyBucket)
{
// 前一個是空桶
nMaxGap = vecBucketMin[nBucketIndex] - nPreMax;
}
nPreMax = vecBucketMax[nBucketIndex];
nEmptyBucket = false;
}
else
{
// 空桶
nEmptyBucket = true;
}
}
return nMaxGap;
}