leetcode 39 组合总和

 问题描述:

   从一个文件中读取 整型数组数据,并通过算法 输出该数据 组合和的情况。

package lc.mqproducer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ConvenienceStoreHomeWorkDemo {
    public static void main(String[] args) {
        //需要查找的文件全路径
        String fileUrl = "D:\\IdeaWorkSpace\\lcmyself\\microserviceparent2020\\microservice-lcintegratedproject\\src\\main\\java\\lc\\mqproducer\\nums.txt";
        //目标值
        int target = 4;
        doConvenienceStoreHomeWork(fileUrl, target);
    }

    private static void doConvenienceStoreHomeWork(String fileUrl, int target) {
        try {
            //1.查找文件 并最终转化为最终解析完的整型数组
            int[] candidates = findFileAndSolve2IntegArr(fileUrl);
            //2.解决leetcode 39组合总和问题 dp方式
            List<List<Integer>> list = combinationSum2(candidates, target);
            System.out.println("最终结果:" + list);
        } catch (Exception e) {
            throw e;
        }
    }

    private static int[] findFileAndSolve2IntegArr(String fileUrl) throws RuntimeException {
        FileInputStream fis = null;
        int[] array = null;
        try {
            File f = new File(fileUrl);
            if (f.exists() && f.isFile()) {
                if (f.length() > 1024) { //校验文件尺寸是否超过1M
                    throw new RuntimeException("文件过大 已超过1M,请选择其他文件");
                }
            } else {
                throw new RuntimeException("文件或目录不存在或不是一个标准文件");
            }
            fis = new FileInputStream(f);
            int fileCapacity = fis.available();
            byte[] buf = new byte[fileCapacity];//定义一个刚刚好的缓冲区,不用再循环了。
            fis.read(buf);
            String transferFileData2Str = new String(buf);//解析转换文件内容
            //解析内容为整型数组并校验文件内容格式, 若存在非整型数据  lambda表达式流异常会被catch
            array = Arrays.asList(transferFileData2Str.split(",")).stream().mapToInt(Integer::parseInt).toArray();
            System.out.println("文件内容解析后的整型数组为array:" + Arrays.toString(array));
        } catch (NumberFormatException e) {
            throw new RuntimeException("文件中包含非整数内容,请重新修改文件内容");
        } catch (FileNotFoundException e) {
            throw new RuntimeException("文件未被找到");
        } catch (IOException e) {
            throw new RuntimeException("文件流解析存在异常");
        } catch (Exception e) {
            throw new RuntimeException("查找文件 系统内部其他异常");
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                throw new RuntimeException("IO流关闭异常");
            }
        }
        return array;
    }

    public static List<List<Integer>> combinationSum2(int[] candidates, int target) {
        try {
            if (candidates == null) {
                return new ArrayList<>();
            }
            Arrays.sort(candidates);//对数据排序
            return combinationSum(candidates, target, 0);
        } catch (Exception e) {//兜底 leetcode 39算法内部异常
            throw new RuntimeException("系统内部 leetcode 39算法异常");
        }
    }

    /**
     * leetcode 39算法 动态规划思路
     * 设原数组为aa,返回值为f(n)f(n),那么对于其中第i项来说:
     * 如果a[i] = targeta[i]=target,那么它一个数就成为一个组合;
     * 如果a[i] < targeta[i]<target,那么a[i]a[i]与f(n - a[i])f(n−a[i])中所有List都构成满足条件的组合;
     * 如果a[i] > targeta[i]>target,无解。
     * 作者:LittleFogCat
     * 链接:https://leetcode-cn.com/problems/combination-sum/solution/dong-tai-gui-hua-39-zu-he-zong-he-by-lit-ko8e/
     * 来源:力扣(LeetCode)
     * 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
     */
    public static List<List<Integer>> combinationSum(int[] candidates, int target, int start) {
        List<List<Integer>> r = new ArrayList<>();
        for (int i = start; i < candidates.length; i++) {
            int num = candidates[i];
            if (target == num) {
                List<Integer> list = new ArrayList<>();
                list.add(num);
                r.add(list);
            }
            if (target > num) {
                int nTarget = target - num;
                List<List<Integer>> nR = combinationSum(candidates, nTarget, i + 1);
                for (List<Integer> list : nR) {
                    list.add(num);
                }
                r.addAll(nR);
            }
            while (i + 1 < candidates.length && candidates[i + 1] == candidates[i]) i++;
        }
        return r;
    }

}

猜你喜欢

转载自blog.csdn.net/CoderTnT/article/details/114170468
今日推荐