找零钱问题-图的深度优先

题目

这是今年华为校招的一道测试题,题目为:
我们知道人民币有1、2、5、10、20、50、100这几种面值。现在给你n(1≤n≤250)元,让你计算换成用上面这些面额表示且总数不超过100张,共有几种。比如4元,能用4张1元、2张1元和1张2元、2张2元,三种表示方法。

思路

根据{1、2、5、10、20、50、100}构建一张 n行7列的图,利用图的深度优先收索算法求解。

代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;

public class Main {

    public static void main(String[] args) {
        Main main = new Main();
        int[] a = { 1, 2, 5, 10, 20, 50, 100 };
        int n = 5;
        main.f1(a, n);
    }

    private void f1(int[] a, int n) {
        if (n <= 0) {
            System.out.println(0);
            return;
        }
        HashSet<String> arr = new HashSet<String>();
        ArrayList<Integer> list = new ArrayList<Integer>();
        getResult(a, n, 0, arr, list);
        System.out.println("共有:" + arr.size() + "种\n分别是:");
        for (String str : arr) {
            System.out.println(str);
        }
    }

    private void getResult(int[] a, int n, int sum, HashSet<String> arr,
            ArrayList<Integer> list) {
        if (sum > n) {
            return;
        }
        if (sum == n && arr.size() <= 100) {
            StringBuffer sb = new StringBuffer();
            Collections.sort(list); // 排序去重
            for (int i = 0; i < list.size(); i++) {
                sb.append(list.get(i) + " ");
            }
            arr.add(sb.toString());
            return;
        }

        for (int i = 0; i < a.length; i++) {
            sum += a[i];
            list.add(a[i]);
            // 深度优先
            getResult(a, n, sum, arr, list);
            // 回溯
            sum -= a[i];
            list.remove((Object) a[i]);
        }
    }
}

结果:

共有:4种
分别是:
1 1 1 1 1 
1 2 2 
5 
1 1 1 2 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值