[アルゴリズム-Javaの実装]お金を交換する方法の数(暴力的な再帰メソッド)

[アルゴリズム-Javaの実装]お金を交換する方法の数(暴力的な再帰メソッド)

1.問題の説明:

整数配列arrが与えられた場合、arrの値は正であり、繰り返されません。各値は金種の通貨を表し、各通貨には任意の通貨を使用できます。

交換される金額を表す整数のターゲットが与えられた場合、お金を交換する方法の数を見つけます

2.質問の回答:

質問があります暴力的再帰法、記憶探索法、動的計画法、この記事では、問題を解決するときに最も考えやすい暴力的な再帰を紹介します

暴力的な再帰は計算で多くの繰り返し計算がありますが、筆記試験のインタビューでは、残忍な再帰は問題を解決するためのアイデアです。メモリ検索と動的プログラミングは、ブルートフォース再帰に基づく最適化方法です

例えば:

arr = [5,10,25,1]、target = 0

0元を形成する方法は1つあります。つまり、すべての通貨が使用されていない場合は、0が返されます。

arr = [5,10,25,1]、target = 15

15元を構成する方法は6つあります。5元3枚、5元1枚+ 10元1枚、10元1枚+1元5枚、1元10枚+1枚5元、5元2枚。元+ 5枚1元、15枚1元なので6を返します。

アイデア:暴力的な再帰

arr = [5,10,25,1]、target = 1000

** 1。** 5元通貨のシートが0枚の場合、残りの1000を[10,25,1]とすると、最終的なメソッド番号はres1として記録されます。

** 2。** 5元の通貨を使用し、[10,25,1]で残りの995を形成すると、最終的なメソッド番号がres2として記録されます。

** 3。** 5元通貨を2枚使用し、残りの990を[10,25,1]にして、最終的なメソッド番号をres3として記録します。

** 201。** 5元通貨200枚で、残りの0を[10,25,1]とし、最終的なメソッド番号をres201として記録します。

その場合、res1 + res2 + res3 + ... + res201がメソッドの最終的な総数になります。

3.アルゴリズム分析:

1.時間計算量はO(N)であり、配列をトラバースします。最悪の場合の時間計算量はO(N乗のターゲット)です。

2.余分なスペースの複雑さはO(N)であり、再帰スタックの深さは配列の長さです。

3.3。再帰:再帰とは、プログラムの実行中に自分自身を呼び出すことを意味し、再帰プロセスはスタックのプロセスです。

再帰を使用する場合は、1。再帰関数の設計方法2.再帰の終了条件を考慮する必要があります。

コードは以下のように表示されます

import java.util.Scanner;

/**
 * @author hkd
 * 
 * 问题:换钱的方法数 
 暴力递归法
 *
 */

public class ExchangeMoney {
    
    
	public static void main(String[] args) {
    
    
		Scanner in = new Scanner(System.in);
		String s = in.nextLine();
		String[] str = s.split(",");
		int target = in.nextInt();
		int[] arr = new int[str.length];
		for (int i = 0; i < arr.length; i++) {
    
    
			arr[i] = Integer.parseInt(str[i]);
		}
		int result = getResult(arr, 0, target);
		System.out.println(result);

	}

	public static int getResult(int[] arr, int index, int target) {
    
    
		if (arr.length == 0 || arr == null || target < 0) {
    
    
			return 0;
		} else {
    
    
			return process(arr, index, target);
		}
	}
     //实现(暴力递归)
	public static int process(int[] arr, int index, int target) {
    
    
		// res记录结果数
		int res = 0;
		// 递归终止条件,index是否已经到达数组最后
		// 此时当target为0时,表示此方法可行,res置1
		if (index == arr.length) {
    
    
			res = target == 0 ? 1 : 0;
		} else {
    
    
			for (int i = 0; arr[index] * i <= target; i++) {
    
    
				res += process(arr, index + 1, target - arr[index] * i);
			}
		}
		return res;

	}
}

おすすめ

転載: blog.csdn.net/hkdhkdhkd/article/details/111321295