摘要:一個(gè)面試題一個(gè)數(shù)組找出這樣的三個(gè)元素它們的和與目標(biāo)值最接近如原始數(shù)組目標(biāo)值這樣的三個(gè)元素算法沒(méi)有想到什么好的算法可以快捷的找到這樣的三個(gè)元素只想到了窮舉法即找出所有的任意三元素?cái)?shù)組長(zhǎng)度放到優(yōu)先隊(duì)列中按三個(gè)元素的和與目標(biāo)值的差值絕對(duì)值進(jìn)行排序
一個(gè)面試題
算法一個(gè)數(shù)組 找出這樣的三個(gè)元素 它們的和與目標(biāo)值最接近
如
原始數(shù)組: [15, 27, 31, 33, 39, 44, 50, 57, 86, 91]
目標(biāo)值: 98
這樣的三個(gè)元素:15,33,50 (15+33+50=98)
沒(méi)有想到什么好的算法 可以快捷的找到這樣的三個(gè)元素
只想到了窮舉法 即
找出所有的任意三元素 C(數(shù)組長(zhǎng)度,3)
放到優(yōu)先隊(duì)列中 按三個(gè)元素的和與目標(biāo)值的差值(絕對(duì)值)進(jìn)行排序
第一個(gè)即是與目標(biāo)值最接近的三元素
偽代碼// 得到所有的三元素組合列表 如["1,2,3", "4,5,6" , ...] List詳細(xì)介紹 如何找到一個(gè)數(shù)組中的所有的X元素組合allUniqueThreeElements = getAllUniqueThreeElements(a,3); // 三元素列表轉(zhuǎn)成對(duì)象 對(duì)象中提供了這樣的方法:getDiff (計(jì)算三元素的和與目標(biāo)值的差值(絕對(duì)值)) List threeElementsList = new ArrayList<>(); for (String s : allUniqueThreeElements) { elementsList.add(new ThreeElements(s)); } // 構(gòu)造優(yōu)先隊(duì)列 按三元素的和與目標(biāo)值的差值(絕對(duì)值)進(jìn)行排序 優(yōu)先隊(duì)列默認(rèn)大小為三元素組合列表大小 PriorityQueue pq = new PriorityQueue<>(threeElementsList.size(),comparingInt(o -> o.getDiff(target))); // 將三元素組合對(duì)象 逐一放到優(yōu)先隊(duì)列中 for (ThreeElements e : threeElementsList) { pq.offer(e); } ThreeElements poll = pq.poll(); // 優(yōu)先隊(duì)列中 第一個(gè)即為要找的三元素
即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ù)制三份 每一份中 取一個(gè)元素 不重復(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 | 超過(guò)最大索引值 從前一位開(kāi)始遞增 同時(shí)逐個(gè)更新后面的值 即后一位的值 = 前一位 + 1 |
0 | 2 | 3 | 1,3,4 |
0 | 2 | 4 | 1,3,5 |
0 | 2 | 5 | 超過(guò)最大索引值 從前一位開(kāi)始遞增 |
0 | 3 | 4 | 1,4,5 |
0 | 3 | 5 | 超過(guò)最大索引值 從前一位開(kāi)始遞增 |
0 | 4 | 5 | 超過(guò)最大索引值 從更一位開(kāi)始遞增 |
1 | 2 | 3 | 2,3,4 |
1 | 2 | 4 | 2,3,5 |
1 | 2 | 5 | 超過(guò)最大索引值 從前一位開(kāi)始遞增 |
1 | 3 | 4 | 2,4,5 |
1 | 3 | 5 | 超過(guò)最大索引值 從前一位開(kāi)始遞增 |
1 | 4 | 5 | 超過(guò)最大索引值 從更一位開(kāi)始遞增 |
2 | 3 | 4 | 3,4,5 |
2 | 3 | 5 | 超過(guò)最大索引值 從前一位開(kāi)始遞增 |
2 | 4 | 5 | 超過(guò)最大索引值 從更一位開(kāi)始遞增 |
3 | 4 | 5 | 超過(guò)最大索引值 且此時(shí)不存在更前一位了 退出 |
/** * * @param indexArray 索引數(shù)組 * @param maxIndexValue 最大索引值 * @param startIndex indexArray中從此位開(kāi)始遞增 * @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]++; // 從此位開(kāi)始遞增 if(indexArray[startIndex] > maxIndexValue){ // 超過(guò)最大索引值 從前一位開(kāi)始遞增 return next(indexArray,maxIndexValue,startIndex-1); }else{ // 同時(shí)逐個(gè)累加之后的元素 后一位的值 = 前一位+1 for (int i = startIndex+1; i < indexArray.length; i++) { indexArray[i] = indexArray[i-1]+1; if(indexArray[i] > maxIndexValue){ if(startIndex -1 < 0){ // 如果是從第一位開(kāi)始遞增的 即不存在更前一位了 則退出遞歸 return false; } return next(indexArray,maxIndexValue,startIndex-1); } } return true; } }
測(cè)試代碼
@Test public void test_next(){ // 測(cè)試從一個(gè)數(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; // 從末位開(kāi)始遞增 // 驗(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í)候 如從一個(gè)數(shù)組中得到所有一個(gè)元素的組合 即C(n,1) 測(cè)試沒(méi)有通過(guò)
@Test public void test_next_and_only_choose_one_element(){ // 測(cè)試一些更極端的情況 如 一個(gè)數(shù)組中選出所有1個(gè)元素的組合(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ù)代碼 將判斷最后沒(méi)有下一組的代碼給提取出來(lái)了
private boolean next(final int[] indexArray, final int maxIndexValue, int startIndex){ if(startIndex < 0){ // 如果不存在更前一位了 則退出遞歸 return false; } indexArray[startIndex]++; // 從此位開(kāi)始遞增 if(indexArray[startIndex] > maxIndexValue){ // 超過(guò)最大索引值 從前一位開(kāi)始遞增 return next(indexArray,maxIndexValue,startIndex-1); }else{ // 同時(shí)逐個(gè)累加之后的元素 后一位的值 = 前一位+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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/66647.html
摘要:但不是和的最長(zhǎng)公共子序列,而序列和也均為和的最長(zhǎng)公共子序列,長(zhǎng)度為,而和不存在長(zhǎng)度大于等于的公共子序列。最長(zhǎng)公共子序列給定序列和,從它們的所有公共子序列中選出長(zhǎng)度最長(zhǎng)的那一個(gè)或幾個(gè)。為和的最長(zhǎng)公共子序列長(zhǎng)度。 最長(zhǎng)公共子序列(Longest Common Subsequence LCS)是從給定的兩個(gè)序列X和Y中取出盡可能多的一部分字符,按照它們?cè)谠蛄信帕械南群蟠涡蚺帕械玫?。LCS問(wèn)...
摘要:第行把具名元組以的形式返回。對(duì)序列使用和通常號(hào)兩側(cè)的序列由相同類型的數(shù)據(jù)所構(gòu)成當(dāng)然不同類型的也可以相加,返回一個(gè)新序列。從上面的結(jié)果可以看出,它雖拋出了異常,但仍完成了操作查看字節(jié)碼并不難,而且它對(duì)我們了解代碼背后的運(yùn)行機(jī)制很有幫助。 《流暢的Python》筆記。接下來(lái)的三篇都是關(guān)于Python的數(shù)據(jù)結(jié)構(gòu),本篇主要是Python中的各序列類型 1. 內(nèi)置序列類型概覽 Python標(biāo)準(zhǔn)庫(kù)...
摘要:使用位運(yùn)算數(shù)組只出現(xiàn)一次數(shù)字的數(shù)組得到最低的有效位,即兩個(gè)數(shù)不同的那一位看完上面的解法,我腦海中只有問(wèn)號(hào)的存在,啥意思啊下面就讓我們簡(jiǎn)單了解一下位運(yùn)算并解析一下這三道題目。另,負(fù)數(shù)按補(bǔ)碼形式參加按位與運(yùn)算。你可做過(guò)這幾道題? 在面試的準(zhǔn)備過(guò)程中,刷算法題算是必修課,當(dāng)然我也不例外。某天,我刷到了一道神奇的題目: # 136. 只出現(xiàn)一次的數(shù)字 給定一個(gè)非空整數(shù)數(shù)組,除了某個(gè)元素只出現(xiàn)一次以外...
閱讀 2382·2021-11-25 09:43
閱讀 2996·2019-08-30 15:52
閱讀 1958·2019-08-30 15:44
閱讀 1039·2019-08-30 10:58
閱讀 832·2019-08-29 18:43
閱讀 3275·2019-08-29 18:36
閱讀 2387·2019-08-29 17:02
閱讀 1516·2019-08-29 17:01