每週一個 Algorithm,Review 一篇英文文章,總結一個工做中的技術 Tip,以及 Share 一個傳遞價值觀的東西!html
題目:Combination Sum (數字組合)java
描述:算法
給定一個無重複元素的數組 candidates 和一個目標數 target ,找出 candidates 中全部能夠使數字和爲 target 的組合。數組
candidates 中的數字能夠無限制重複被選取。ide
說明:post
解題過程:學習
通常要求列出全部組合的題目,均可以用回溯法來解決。spa
回溯的核心思想是:code
1.經過深度優先的方式求解。htm
2.每探索一個節點時,判斷是否包含可行解。
3.當目前不符合要求時,回退到上一步繼續探索。
解法:
1 import java.util.ArrayList; 2 import java.util.Arrays; 3 import java.util.List; 4 import java.util.stream.IntStream; 5 6 /** 7 * description : https://leetcode.com/problems/combination-sum/ 8 * contains unique/duplicates solutions 9 * 題目描述 : https://leetcode-cn.com/problems/combination-sum/ 10 * 包含 惟一/重複 兩種解題思路 11 */ 12 public class CombinationSum { 13 14 public List<List<Integer>> combine(int[] candidates, int target) { 15 Integer[] objects = 16 IntStream.of(candidates).boxed().toArray(Integer[]::new); 17 Arrays.sort(objects); 18 List<List<Integer>> result = new ArrayList<>(); 19 if (target > 0) { 20 backtrace(result, new ArrayList<>(), target, objects, 0); 21 } 22 return result; 23 } 24 25 private void backtrace(List<List<Integer>> result, 26 List<Integer> arr, int remain, 27 Integer[] candidates, int index) { 28 if (remain < 0) { 29 return; 30 } else if (remain == 0) { 31 result.add(new ArrayList<>(arr)); 32 } else { 33 for (int i = index; i < candidates.length; i++) { 34 arr.add(candidates[i]); 35 backtrace(result, arr, remain - candidates[i], 36 candidates, i); 37 arr.remove(arr.size() - 1); 38 } 39 } 40 } 41 42 public List<List<Integer>> combineUnique(int[] candidates, 43 int target) { 44 Integer[] objects = 45 IntStream.of(candidates).boxed().toArray(Integer[]::new); 46 List<List<Integer>> result = new ArrayList<>(); 47 Arrays.sort(objects); 48 if (target > 0) { 49 backtraceUnqiue(result, new ArrayList<>(), target, 50 objects, 0); 51 } 52 return result; 53 } 54 55 private void backtraceUnqiue(List<List<Integer>> result, 56 List<Integer> arr, int remain, 57 Integer[] candidates, int index) { 58 if (remain < 0) { 59 return; 60 } else if (remain == 0) { 61 if (!result.contains(arr)) { 62 result.add(new ArrayList<>(arr)); 63 } 64 } else { 65 for (int i = index; i < candidates.length; i++) { 66 arr.add(candidates[i]); 67 backtraceUnqiue(result, arr, remain - candidates[i], 68 candidates, i + 1); 69 arr.remove(arr.size() - 1); 70 } 71 } 72 } 73 74 75 }
無
舉個例子,某一面包房要把早晨製做的麪包分發到全市的全部合做店鋪裏,店鋪須要的麪包數量各異,位置分散,而且一輛車運不完,要用多輛車給全部店鋪配送。麪包房要找出一個辦法,用最少的車,行駛最短路程,送完全部麪包。
這個就是運籌學中的車輛路徑規劃問題(VRP), 求解這個問題有不少方法,我介紹一種思路比較清晰,實現比較簡單的方法 C-W 節約算法。
算法的核心思想是經過計算節點間的 節約距離, 根據節約距離來選擇路徑,從而節省最多的路程。
能夠經過這個例子來理解: 節約里程法
具體實現參看我另外一篇博文:基於C-W節約算法的車輛路徑規劃問題的Java實現
人生苦難重重,若是你不解決問題,你就會成爲問題。解決部分問題須要部分的自律,解決所有問題須要所有的自律。自律包括四部分:推遲知足感, 承擔責任,忠於事實,平衡。