最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

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

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

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

重頭戲來了!??!整個(gè)代碼的流程如下:

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

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

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

3.我們?cè)俅伪闅v一遍數(shù)組,將每一個(gè)數(shù),放入到相應(yīng)的桶里。

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

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

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

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

正是因?yàn)檫@個(gè)空桶的存在,會(huì)將很多種計(jì)算的可能性直接抹殺掉。說的具體點(diǎn),假設(shè)一個(gè)桶的存儲(chǔ)數(shù)的范圍是0~9,也就是這個(gè)桶能夠存儲(chǔ)10個(gè)數(shù),既然有一個(gè)空桶的話,那么肯定最后的答案是大于10的。

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

就如上圖的形式,將所有的數(shù)據(jù)都放入相應(yīng)的桶里。因?yàn)橛锌胀暗拇嬖?,所以我們的答案必然是在兩個(gè)不同桶之間的數(shù)據(jù)進(jìn)行相減。而我們?cè)谶M(jìn)行相減的時(shí)候,只需要記錄每個(gè)桶的最大值和最小值即可。也就是說,用后一個(gè)桶的最小值,減前一個(gè)桶的最大值。以這樣的形式,循環(huán)N次,將每?jī)蓚€(gè)相鄰的桶進(jìn)行計(jì)算,就能得到最終的答案。

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

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

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

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

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

import java.util.Arrays;

public class Code01_CalcTwoNumDiv {
    public static void main(String[] args) {
        int testTime = 5000; //測(cè)試次數(shù)
        int N = 50; //數(shù)組長(zhǎng)度
        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? "正確" : "錯(cuò)誤");
    }

    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; //如果最大值和最小值相等,說明這個(gè)數(shù)組只有這一個(gè)數(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
        }

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

    public static int getBit(int num, int len, int max, int min) {
        return ((num - min) * len) / (max - min); //計(jì)算num應(yīng)該存儲(chǔ)在哪個(gè)桶
    }

    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;
    }
}

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

相關(guān)文章

  • SpringBoot整合redis使用緩存注解詳解

    SpringBoot整合redis使用緩存注解詳解

    這篇文章主要介紹了SpringBoot整合redis使用緩存注解詳解,@Cacheable在方法執(zhí)行前判斷對(duì)應(yīng)緩存是否存在,如果存在直接返回緩存結(jié)果,否者執(zhí)行方法將結(jié)果緩存,適用于查詢類,需要的朋友可以參考下
    2024-01-01
  • Java與Unix時(shí)間戳的相互轉(zhuǎn)換詳解

    Java與Unix時(shí)間戳的相互轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了Java與Unix時(shí)間戳的相互轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 在Java中如何避免創(chuàng)建不必要的對(duì)象

    在Java中如何避免創(chuàng)建不必要的對(duì)象

    作為Java開發(fā)者,我們每天創(chuàng)建很多對(duì)象,但如何才能避免創(chuàng)建不必要的對(duì)象呢?這需要我們好好學(xué)習(xí),這篇文章主要給大家介紹了關(guān)于在Java中如何避免創(chuàng)建不必要對(duì)象的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • java中對(duì)象的比較equal、Comparble、Comparator的區(qū)別

    java中對(duì)象的比較equal、Comparble、Comparator的區(qū)別

    本文主要介紹了java中對(duì)象的比較equal、Comparble、Comparator的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 基于springMVC web.xml中的配置加載順序

    基于springMVC web.xml中的配置加載順序

    這篇文章主要介紹了springMVC web.xml中的配置加載順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java如何利用狀態(tài)模式(state pattern)替代if else

    Java如何利用狀態(tài)模式(state pattern)替代if else

    這篇文章主要給大家介紹了關(guān)于Java如何利用狀態(tài)模式(state pattern)替代if else的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java基礎(chǔ)知識(shí)之成員變量和局部變量淺顯易懂總結(jié)

    Java基礎(chǔ)知識(shí)之成員變量和局部變量淺顯易懂總結(jié)

    從語法形式上,看成員變量是屬于類的,而局部變量是在方法中定義的變量或是方法的參數(shù);成員變量可以被public,private,static等修飾符所修飾,而局部變量不能被訪問控制修飾符及static所修飾
    2021-09-09
  • Springboot上傳文件時(shí)提示405問題及排坑過程

    Springboot上傳文件時(shí)提示405問題及排坑過程

    這篇文章主要介紹了Springboot上傳文件時(shí)提示405問題及排坑過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Java基于二叉查找樹實(shí)現(xiàn)排序功能示例

    Java基于二叉查找樹實(shí)現(xiàn)排序功能示例

    這篇文章主要介紹了Java基于二叉查找樹實(shí)現(xiàn)排序功能,結(jié)合實(shí)例形式分析了Java二叉查找樹的定義、遍歷及排序等相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • mybatis 解決從列名到屬性名的自動(dòng)映射失敗問題

    mybatis 解決從列名到屬性名的自動(dòng)映射失敗問題

    這篇文章主要介紹了mybatis 解決從列名到屬性名的自動(dòng)映射失敗問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評(píng)論

石屏县| 本溪| 浠水县| 大荔县| 龙泉市| 青神县| 太湖县| 灵宝市| 钟山县| 图片| 岱山县| 济源市| 万载县| 梓潼县| 宁蒗| 霍城县| 卢龙县| 车致| 察雅县| 曲靖市| 体育| 柞水县| 灵台县| 荆门市| 溧阳市| 平凉市| 麻江县| 新乡市| 南安市| 商南县| 夏邑县| 昌黎县| 山东省| 墨玉县| 如东县| 富平县| 阿拉善右旗| 奉节县| 张家川| 万载县| 三门峡市|