成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

得到一個數(shù)組中任意X個元素的所有組合 即C(n,m)

haoguo / 1406人閱讀

摘要:一個面試題一個數(shù)組找出這樣的三個元素它們的和與目標(biāo)值最接近如原始數(shù)組目標(biāo)值這樣的三個元素算法沒有想到什么好的算法可以快捷的找到這樣的三個元素只想到了窮舉法即找出所有的任意三元素數(shù)組長度放到優(yōu)先隊(duì)列中按三個元素的和與目標(biāo)值的差值絕對值進(jìn)行排序

一個面試題

一個數(shù)組 找出這樣的三個元素 它們的和與目標(biāo)值最接近

原始數(shù)組: [15, 27, 31, 33, 39, 44, 50, 57, 86, 91]
目標(biāo)值: 98
這樣的三個元素:15,33,50 (15+33+50=98)

算法

沒有想到什么好的算法 可以快捷的找到這樣的三個元素
只想到了窮舉法 即

找出所有的任意三元素 C(數(shù)組長度,3)

放到優(yōu)先隊(duì)列中 按三個元素的和與目標(biāo)值的差值(絕對值)進(jìn)行排序

第一個即是與目標(biāo)值最接近的三元素

偽代碼
// 得到所有的三元素組合列表 如["1,2,3", "4,5,6" , ...]
List allUniqueThreeElements = getAllUniqueThreeElements(a,3);

// 三元素列表轉(zhuǎn)成對象  對象中提供了這樣的方法:getDiff (計算三元素的和與目標(biāo)值的差值(絕對值))
List threeElementsList = new ArrayList<>();
for (String s : allUniqueThreeElements) {
    elementsList.add(new ThreeElements(s));
}
// 構(gòu)造優(yōu)先隊(duì)列 按三元素的和與目標(biāo)值的差值(絕對值)進(jìn)行排序 優(yōu)先隊(duì)列默認(rèn)大小為三元素組合列表大小
PriorityQueue pq = new PriorityQueue<>(threeElementsList.size(),comparingInt(o -> o.getDiff(target))); 

// 將三元素組合對象 逐一放到優(yōu)先隊(duì)列中
for (ThreeElements e : threeElementsList) {
    pq.offer(e);
}

ThreeElements poll = pq.poll(); // 優(yōu)先隊(duì)列中 第一個即為要找的三元素
詳細(xì)介紹 如何找到一個數(shù)組中的所有的X元素組合

即C(n,m)

如 數(shù)組 [1,2,3,4,5] 找出所有的元素組合

index 0 1 2 3 4
copy1 1 2 3 4 5
copy2 1 2 3 4 5
copy3 1 2 3 4 5

相當(dāng)于將同一數(shù)組復(fù)制三份 每一份中 取一個元素 不重復(fù)即可

這樣的取法

copy1 copy2 copy3 -
0 1 2 1,2,3
0 1 3 1,2,4
0 1 4 1,2,5
0 1 5 超過最大索引值 從前一位開始遞增 同時逐個更新后面的值 即后一位的值 = 前一位 + 1
0 2 3 1,3,4
0 2 4 1,3,5
0 2 5 超過最大索引值 從前一位開始遞增
0 3 4 1,4,5
0 3 5 超過最大索引值 從前一位開始遞增
0 4 5 超過最大索引值 從更一位開始遞增
1 2 3 2,3,4
1 2 4 2,3,5
1 2 5 超過最大索引值 從前一位開始遞增
1 3 4 2,4,5
1 3 5 超過最大索引值 從前一位開始遞增
1 4 5 超過最大索引值 從更一位開始遞增
2 3 4 3,4,5
2 3 5 超過最大索引值 從前一位開始遞增
2 4 5 超過最大索引值 從更一位開始遞增
3 4 5 超過最大索引值 且此時不存在更前一位了 退出
對應(yīng)的代碼
    /**
     * 
     * @param indexArray 索引數(shù)組
     * @param maxIndexValue 最大索引值
     * @param startIndex indexArray中從此位開始遞增
     * @return
     */
    private boolean next(final int[] indexArray, final int maxIndexValue, int startIndex){
//        System.out.println("indexArray: "+Arrays.toString(indexArray));
//        System.out.println("startIndex: "+startIndex);
        indexArray[startIndex]++; // 從此位開始遞增
        if(indexArray[startIndex] > maxIndexValue){ // 超過最大索引值 從前一位開始遞增
            return next(indexArray,maxIndexValue,startIndex-1);
        }else{
            // 同時逐個累加之后的元素 后一位的值 = 前一位+1
            for (int i = startIndex+1; i < indexArray.length; i++) {
                indexArray[i] = indexArray[i-1]+1;
                if(indexArray[i] > maxIndexValue){
                    if(startIndex -1 < 0){ // 如果是從第一位開始遞增的 即不存在更前一位了 則退出遞歸
                        return false;
                    }
                    return next(indexArray,maxIndexValue,startIndex-1);
                }
            }
            return true;
        }
    }

測試代碼

    @Test
    public void test_next(){
        // 測試從一個數(shù)組中得到所有的三元素組合
        int[] a = {1, 2, 3, 4, 5}; // 數(shù)組
        int maxIndexValue = a.length-1; // 最大索引值
        int[] indexArray = {0,1,2}; // 初始化索引數(shù)組
        int startIndex = indexArray.length-1; // 從末位開始遞增

        // 驗(yàn)證  [0,1,2] --> [0,1,3]
        boolean next = next(indexArray, maxIndexValue, startIndex);
        assertTrue(next);
        assertArrayEquals(new int[]{0,1,3}, indexArray);

        // 驗(yàn)證 [0,1,4] --> [0,2,3]
        indexArray = new int[]{0, 1, 4};
        next = next(indexArray, maxIndexValue, startIndex);
        assertTrue(next);
        assertArrayEquals(new int[]{0,2,3}, indexArray);

        // 驗(yàn)證 [0,3,4] --> [1,2,3]
        indexArray = new int[]{0, 3, 4};
        next = next(indexArray, maxIndexValue, startIndex);
        assertTrue(next);
        assertArrayEquals(new int[]{1,2,3}, indexArray);

        // 驗(yàn)證 [2,3,4] --> X
        indexArray = new int[]{2, 3, 4};
        next = next(indexArray, maxIndexValue, startIndex);
        assertFalse(next);
    }

當(dāng)驗(yàn)證其他一些極端情況的時候 如從一個數(shù)組中得到所有一個元素的組合 即C(n,1) 測試沒有通過

    @Test
    public void test_next_and_only_choose_one_element(){
        // 測試一些更極端的情況 如 一個數(shù)組中選出所有1個元素的組合(C(n,1))
        final int[] a = {1, 2, 3, 4, 5};
        int maxIndexValue = a.length-1;
        int[] indexArray = {0};
        int startIndex = indexArray.length-1;


        //驗(yàn)證 [0] -> [1]
        boolean next = next(indexArray, maxIndexValue, startIndex);
        assertTrue(next);
        assertArrayEquals(new int[]{1},indexArray);
        System.out.println();
        // 驗(yàn)證 [4] -> X
        indexArray = new int[]{4};
        next = next(indexArray, maxIndexValue, startIndex);
        assertFalse(next);
    }

修復(fù)代碼 將判斷最后沒有下一組的代碼給提取出來了

    private boolean next(final int[] indexArray, final int maxIndexValue, int startIndex){
        if(startIndex < 0){ // 如果不存在更前一位了 則退出遞歸
            return false;
        }
        indexArray[startIndex]++; // 從此位開始遞增
        if(indexArray[startIndex] > maxIndexValue){ // 超過最大索引值 從前一位開始遞增
            return next(indexArray,maxIndexValue,startIndex-1);
        }else{
            // 同時逐個累加之后的元素 后一位的值 = 前一位+1
            for (int i = startIndex+1; i < indexArray.length; i++) {
                indexArray[i] = indexArray[i-1]+1;
                if(indexArray[i] > maxIndexValue){
                    return next(indexArray,maxIndexValue,startIndex-1);
                }
            }
            return true;
        }
    }
參考文檔

http://wiki.jikexueyuan.com/p...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66647.html

相關(guān)文章

  • javasm>cm>ript 最長公共子序列

    摘要:但不是和的最長公共子序列,而序列和也均為和的最長公共子序列,長度為,而和不存在長度大于等于的公共子序列。最長公共子序列給定序列和,從它們的所有公共子序列中選出長度最長的那一個或幾個。為和的最長公共子序列長度。 最長公共子序列(Longest Common Subsequence LCS)是從給定的兩個序列X和Y中取出盡可能多的一部分字符,按照它們在原序列排列的先后次序排列得到。LCS問...

    Xufc 評論0 收藏0
  • Pythom>nm>學(xué)習(xí)之路21-序列構(gòu)成數(shù)組

    摘要:第行把具名元組以的形式返回。對序列使用和通常號兩側(cè)的序列由相同類型的數(shù)據(jù)所構(gòu)成當(dāng)然不同類型的也可以相加,返回一個新序列。從上面的結(jié)果可以看出,它雖拋出了異常,但仍完成了操作查看字節(jié)碼并不難,而且它對我們了解代碼背后的運(yùn)行機(jī)制很有幫助。 《流暢的Python》筆記。接下來的三篇都是關(guān)于Python的數(shù)據(jù)結(jié)構(gòu),本篇主要是Python中的各序列類型 1. 內(nèi)置序列類型概覽 Python標(biāo)準(zhǔn)庫...

    ralap 評論0 收藏0
  • 由三道 Leetm>Cm>ode 題目簡單了解一下位運(yùn)算

    摘要:使用位運(yùn)算數(shù)組只出現(xiàn)一次數(shù)字的數(shù)組得到最低的有效位,即兩個數(shù)不同的那一位看完上面的解法,我腦海中只有問號的存在,啥意思啊下面就讓我們簡單了解一下位運(yùn)算并解析一下這三道題目。另,負(fù)數(shù)按補(bǔ)碼形式參加按位與運(yùn)算。你可做過這幾道題? 在面試的準(zhǔn)備過程中,刷算法題算是必修課,當(dāng)然我也不例外。某天,我刷到了一道神奇的題目: # 136. 只出現(xiàn)一次的數(shù)字 給定一個非空整數(shù)數(shù)組,除了某個元素只出現(xiàn)一次以外...

    daydream 評論0 收藏0

發(fā)表評論

0條評論

haoguo

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<