無序數組 排序後 最大間隔

本文現轉載他人文章,後續會進行詳細講解。

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章