Advertisement
uopspop

Untitled

Oct 11th, 2017
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.70 KB | None | 0 0
  1. package src.dp;
  2.  
  3. import java.util.Arrays;
  4.  
  5. /**
  6.  * 空間優化
  7.  * The time complexity is O(coins.length · targetVal) and the space complexity is O(targetVal).
  8.  * @author sam
  9.  *
  10.  */
  11. public class DP_myOwnImpl_Space {
  12.     public static void main(String[] args) {
  13.         int[] coins = { 3, 4 };
  14.         int targetVal = 7;
  15.         long[] resultRow = solution01(coins, targetVal);
  16.         System.out.println("final result list: " + Arrays.toString(resultRow));
  17.         System.out.println("final result: " + resultRow[resultRow.length - 1]);
  18.     }
  19.  
  20.     private static long[] solution01(int[] coins, int targetVal) {
  21.  
  22.         // 初始化紀錄過程用map
  23.         long[] resultMap = new long[targetVal + 1]; // 0的狀況都要考慮進去
  24.         Arrays.fill(resultMap, -1);
  25.  
  26.         // 確保硬幣面值有小排到大
  27.         Arrays.sort(coins);
  28.  
  29.         // 當沒有任何零錢時,所有結果都是無限個硬幣才能達到目標
  30.         for (int currTargetVal = 1; currTargetVal <= targetVal; currTargetVal++) {
  31.             int currCoinIndex = 0;
  32.             resultMap[currTargetVal] = Integer.MAX_VALUE;
  33.             printAry(resultMap,currTargetVal);
  34.         }
  35.  
  36.         // 當沒有任何零錢時 + 當目標值為零時
  37.         resultMap[0] = 0;
  38.         printAry(resultMap,0);
  39.  
  40.         // 觀念1: 由小到大算 -> 先由只有一個硬幣的狀況開始,並記錄其最佳化結果,再來使用兩個硬幣,利用之前的結果來計算下去,再來同時用三個、四個,一直到結束
  41.         // 觀念2: 除了第一排只能往左走以外,其餘的每一格皆可以考慮要往上走or往左走
  42.         for (int currCoinIndex = 1; currCoinIndex <= coins.length; currCoinIndex++) {
  43.             int currCoinVal = coins[currCoinIndex - 1];
  44.             for (int currTargetVal = 1; currTargetVal <= targetVal; currTargetVal++) {
  45.                 // 若 當下使用的硬幣面值 > 當前的目標值, 則到表這個硬幣根本不能用,其結果將會等於使用小於此硬幣面值中最大者的結果
  46.                 if (currCoinVal > currTargetVal) {
  47.                     resultMap[currTargetVal] = resultMap[currTargetVal];
  48.                     printAry(resultMap, currTargetVal);
  49.                     // 若不是,則可以選擇要取當前硬幣面值來用,或者不要 -> 兩條路下去,取其中所需硬幣數最小者
  50.                 } else {
  51.                     resultMap[currTargetVal] = Math.min(resultMap[currTargetVal], resultMap[currTargetVal - currCoinVal] + 1);
  52.                     printAry(resultMap, currTargetVal);
  53.                 }
  54.             }
  55.         }
  56.  
  57.         return resultMap;
  58.     }
  59.  
  60.     /** 以下為講解用,非正式解題流程 **/
  61.  
  62.     private static void printAry(long[] resultMap, int targetCol) {
  63.         for (int i = 0; i < resultMap.length; i++) {
  64.             if (Long.compare(i, targetCol) == 0) {
  65.                 System.out.printf("%14d*", resultMap[i]);
  66.             }else {
  67.                 System.out.printf("%15d", resultMap[i]);
  68.             }
  69.         }
  70.         System.out.println();
  71.     }
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement