亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java解決計算相鄰兩個數(shù)的最大差值的問題

 更新時間:2021年12月11日 16:05:00   作者:飛人01_01  
今天給大家?guī)硪坏浪惴}:給定一個數(shù)組,求如果排序之后,相鄰兩數(shù)的最大差值。要求時間復雜度O(N),且要求不能用非基于比較的排序??靵砀S小編一起學習一下如何解決這一問題吧

hello,今天給大家?guī)硪坏浪惴}。這道算法題,是我目前為止,見過最難的一道題。那么到底是怎樣的一道算法題呢?如下:

題目:給定一個數(shù)組, 求如果排序之后, 相鄰兩數(shù)的最大差值。 要求時間復雜度O(N), 且要求不能用非基于比較的排序。

我查了一下,暫時沒有找到一個在線OJ的鏈接,只能自己寫一個對數(shù)器,手動測試了。

當初我看到這個題目的時候,說這怎么可能呢?在一個無序的數(shù)組中,求相鄰兩個數(shù)據(jù)的最大差值??墒俏覀兌贾?,現(xiàn)在基于比較的排序算法,最快也只能夠達到O(N*logN)的水平,而題目明確限制時間復雜度要是O(N),所以想通過基于比較的排序,排序之后再進行遍歷,時間復雜度肯定是達不到要求的。

有人可能也會想說,不是還有基于非比較的排序算法嗎?比如計數(shù)排序、基數(shù)排序、桶排序。但是題目又明確規(guī)定了不能使用基于非比較的排序算法。

這樣的話,想使用排序算法,進行排序,這條路肯定是行不通的。只能另外想其他的辦法。

-------------------------------------------------------------------------------------------我是分割線-----------------------------------------------------------------------------------------

重頭戲來了?。?!整個代碼的流程如下:

1.先遍歷一遍數(shù)組,保存整個數(shù)組的最大值和最小值。

2.假設數(shù)組中一共有N個元素,那么我們就需要準備N+1個桶。

這每一個桶里面,可以存儲一定范圍內(nèi)的數(shù)值,而具體可以存儲多大范圍內(nèi)的數(shù)值,需要用公式去計算。比如:第一個桶存儲0……9之間的數(shù),第二個桶存儲10……19的數(shù)……

3.我們再次遍歷一遍數(shù)組,將每一個數(shù),放入到相應的桶里。

解釋:為什么需要進行以上這3個步驟???這是一個非常值得思考的問題?。?!

由題可知,一共有N個數(shù),但是我們準備了N+1個桶。也就是說我們將每個數(shù)放入相應的桶中,就算這N個數(shù)都在各自的桶里,無論怎么放入,始終會多出來1個空桶。

而我們會根據(jù)一下這個公式,將每個數(shù)放入相應的桶:(arr[i]- min)* N / (max - min)。

以上這個公式,就能夠計算出i位置的數(shù),應該放入哪一個桶里。根據(jù)公式計算,最小值一定會放到第一個桶里,最大值也一定會放到最后一個桶里。那么既然第一個和最后一個桶肯定是有數(shù)據(jù)的,也就是說明那個空桶肯定是中間的某一個桶。

正是因為這個空桶的存在,會將很多種計算的可能性直接抹殺掉。說的具體點,假設一個桶的存儲數(shù)的范圍是0~9,也就是這個桶能夠存儲10個數(shù),既然有一個空桶的話,那么肯定最后的答案是大于10的。

那么既然大于10的話,這兩個數(shù)肯定不會在同一個桶里。這樣的話,我們就排除了桶里面兩個數(shù)據(jù)的情況,只需要考慮相鄰兩個桶之間的數(shù),才可能是最終的答案。

就如上圖的形式,將所有的數(shù)據(jù)都放入相應的桶里。因為有空桶的存在,所以我們的答案必然是在兩個不同桶之間的數(shù)據(jù)進行相減。而我們在進行相減的時候,只需要記錄每個桶的最大值和最小值即可。也就是說,用后一個桶的最小值,減前一個桶的最大值。以這樣的形式,循環(huán)N次,將每兩個相鄰的桶進行計算,就能得到最終的答案。

既然我們只需要每個桶里的最大值和最小值,那就準備兩個數(shù)組maxs和mins,分別存儲即可。代碼如下:

以上就是這道題的所有代碼,代碼不多,但是其中的算法思想我覺得真的是很厲害,很難想象出,想到這個方法的是什么人。

核心就在于那個空桶的存在,抹殺很多的可能性。使其最終的答案只可能存在于相鄰兩個桶之間的數(shù)。

提問:假設給定的某一個數(shù)組,算出來桶的數(shù)據(jù)后,只有一個是空桶。那么最終的答案就一定是這個空桶右邊桶的數(shù)據(jù)減去左邊桶的數(shù)據(jù)嗎?

最后,我將整個代碼全部放到下面,包括了一個對數(shù)器,用于測試以上代碼的正確性。

import java.util.Arrays;

public class Code01_CalcTwoNumDiv {
    public static void main(String[] args) {
        int testTime = 5000; //測試次數(shù)
        int N = 50; //數(shù)組長度
        int range = 1000; //數(shù)據(jù)范圍
        boolean flag = true;
        for (int i = 0; i < testTime; i++) {
            int[] arr = generateArr(N, range);
            int p1 = calcTwoNumDiv(arr);
            int p2 = sortAfter(arr);
            if (p1 != p2) {
                flag = false;
                break;
            }
        }
        System.out.println(flag? "正確" : "錯誤");
    }

    public static int calcTwoNumDiv(int[] array) {
        if (array == null || array.length < 2) {
            return 0;
        }
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int i : array) { //先遍歷一遍數(shù)組,求最大值最小值
            max = Math.max(max, i);
            min = Math.min(min, i);
        }
        if (max == min) {
            return 0; //如果最大值和最小值相等,說明這個數(shù)組只有這一個數(shù)據(jù)
        }
        int len = array.length;
        boolean[] hasNum = new boolean[len + 1];
        int[] maxs = new int[len + 1];
        int[] mins = new int[len + 1];
        //遍歷數(shù)據(jù)
        for (int i = 0; i < array.length; i++) {
            int bit = getBit(array[i], len, max, min); //桶的位置
            maxs[bit] = hasNum[bit] ? Math.max(maxs[bit], array[i]) : array[i]; //更新最大值
            mins[bit] = hasNum[bit] ? Math.min(mins[bit], array[i]) : array[i]; //更新最小值
            hasNum[bit] = true; //始終更新為true
        }

        //第一個桶和最后一個桶,肯定是有數(shù)據(jù)的。
        int preMax = maxs[0];
        int res = Integer.MIN_VALUE; //最終的結果
        for (int i = 1; i <= len; i++) {
            if (hasNum[i]) {
                res = Math.max(res, mins[i] - preMax);
                preMax = maxs[i]; //更新前一個的最大值
            }
        }
        return res;
    }

    public static int getBit(int num, int len, int max, int min) {
        return ((num - min) * len) / (max - min); //計算num應該存儲在哪個桶
    }

    public static int sortAfter(int[] arr) {
        if (arr == null || arr.length < 2) {
            return 0;
        }

        Arrays.sort(arr);
        int res = Integer.MIN_VALUE;
        for (int i = 1; i < arr.length; i++) {
            res = Math.max(res, arr[i] - arr[i - 1]);
        }
        return res;
    }

    public static int[] generateArr(int N , int range) {
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = (int)(Math.random() * range);
        }
        return arr;
    }
}

到此這篇關于Java解決計算相鄰兩個數(shù)的最大差值的問題的文章就介紹到這了,更多相關Java 計算相鄰數(shù)的最大差值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 泛談Java中的不可變數(shù)據(jù)結構

    泛談Java中的不可變數(shù)據(jù)結構

    開發(fā)人員通常認為擁有final引用,或者val在Kotlin或Scala中,足以使對象不可變。這篇博客文章深入研究了不可變引用和不可變數(shù)據(jù)結構,下面小編來和大家一起學習它
    2019-05-05
  • springboot對壓縮請求的處理方法

    springboot對壓縮請求的處理方法

    這篇文章主要介紹了springboot對壓縮請求的處理,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • SpringMVC教程之文件上傳與下載詳解

    SpringMVC教程之文件上傳與下載詳解

    本文將對使用MultipartResolver處理文件上傳的步驟,兩種文件下載方式(直接向response的輸出流中寫入對應的文件流、使用 ResponseEntity<byte[]>來向前端返回文件)等進行詳盡介紹,需要的可以參考一下
    2022-12-12
  • java 中動態(tài)代理(JDK,cglib)實例代碼

    java 中動態(tài)代理(JDK,cglib)實例代碼

    這篇文章主要介紹了java 中動態(tài)代理,這里介紹了JDK 動態(tài)代理與 cglib 動態(tài)代理的相關資料
    2017-04-04
  • Java8新特性之字符串去重介紹

    Java8新特性之字符串去重介紹

    這篇文章主要介紹了Java8新特性之字符串去重介紹,新的字符串去重特性可以幫助減少應用中String對象的內(nèi)存占用,目前該特性只適用于G1垃圾收集器,并且默認不被開啟,需要的朋友可以參考下
    2014-09-09
  • Java字符串拼接+和StringBuilder的比較與選擇

    Java字符串拼接+和StringBuilder的比較與選擇

    Java 提供了兩種主要的方式:使用 "+" 運算符和使用 StringBuilder 類,本文主要介紹了Java字符串拼接+和StringBuilder的比較與選擇,感興趣的可以了解一下
    2023-10-10
  • Java輸出通過InetAddress獲得的IP地址數(shù)組詳細解析

    Java輸出通過InetAddress獲得的IP地址數(shù)組詳細解析

    由于byte被認為是unsigned byte,所以最高位的1將會被解釋為符號位,另外Java中存儲是按照補碼存儲,所以1000 0111會被認為是補碼形式,轉換成原碼便是1111 0001,轉換成十進制數(shù)便是-121
    2013-09-09
  • Java如何把數(shù)組轉換為ArrayList

    Java如何把數(shù)組轉換為ArrayList

    這篇文章主要介紹了Java如何把數(shù)組轉換為ArrayList,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Spring?MVC文件請求處理MultipartResolver詳解

    Spring?MVC文件請求處理MultipartResolver詳解

    這篇文章主要介紹了Spring?MVC文件請求處理詳解:MultipartResolver,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • Java實現(xiàn)獲取銀行卡所屬銀行,驗證銀行卡號是否正確的方法詳解

    Java實現(xiàn)獲取銀行卡所屬銀行,驗證銀行卡號是否正確的方法詳解

    這篇文章主要介紹了Java實現(xiàn)獲取銀行卡所屬銀行,驗證銀行卡號是否正確的方法,結合實例形式詳細分析了java判斷銀行卡歸屬地及有效性的原理與相關實現(xiàn)技巧,需要的朋友可以參考下
    2019-09-09

最新評論