int[]vs arraylist< >()在memoization中,java中的动态编程

tpxzln5u  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(278)

我最近在youtube上看了一个动态编程教程,解释了动态编程,但导师用javascript解决了问题。i、 另一方面,数据结构和算法使用java。同时实现动态规划求解问题。我发现我在使用 int[] 但使用时回答错误 ArrayList<Integer> 因为不知何故,hashmap中已经存储的arraylist正在进行内部修改。
问题:编写一个函数bestsum(targetsum,numbers),它接受targetsum和一个数字数组作为参数,并返回一个数组,该数组包含最短的数字组合,这些数字加起来正好等于目标和。
例子:
bestsum(7,new int[]{2,1,3})=>[3,3,1]//其他可能性,但不回答:[2,2,2,1],[1,1,1,1,1],[2,2,1,1,1]等
bestsum(100,new int[]{2,5,25})=>[25,25,25]
使用int[]的代码:

public class Persist {
    public static HashMap<Integer,int[]> memo = new HashMap<>();
    public static int[] bestSum(int n, int[] arr){
        if(memo.containsKey(n)){
            //System.out.printf("From memo: %d->"+ Arrays.toString(memo.get(n)) +"%n",n);
            return memo.get(n);
        }

        if(n==0)return new int[0];

        if(n<0)return null;

        int[] minn = null;

        for(int i = 0;i<arr.length;i++){

            //recursion
            var temp = bestSum(n-arr[i],arr);

            if(temp!=null){

                // ttemp is used to add arr[i] to the initial arr <<temp>>
                int[] ttemp = new int[temp.length+1];
                System.arraycopy(temp,0,ttemp,0,temp.length);
                ttemp[temp.length] = arr[i];
                temp = ttemp;

                if(minn==null||temp.length<minn.length){
                    minn = temp;
                }
            }
        }
        //System.out.println(n+": "+minn);
        memo.put(n,minn);
        //System.out.println(memo.get(n));
        return minn;
    }
    public static void main(String[] args){
        System.out.println(Arrays.toString(bestSum(7, new int[]{2,1,3})));
    }
}

使用arraylist编码:

public class Persist {
    public static HashMap<Integer,ArrayList<Integer>> memo = new HashMap<>();
    public static ArrayList<Integer> bestSum(int n, int[] arr){
        if(memo.containsKey(n)){
            //System.out.printf("From memo: %d->"+ memo.get(n)+"%n",n);
            return memo.get(n);
        }
        if(n==0)return new ArrayList<>();
        if(n<0)return null;
        ArrayList<Integer> minn = null;
        for(int i = 0;i<arr.length;i++){
            var temp = bestSum(n-arr[i],arr);
            if(temp!=null){
                temp.add(arr[i]);
                if(minn==null||temp.size()<minn.size()){
                    minn = temp;

                }
            }
        }
        //System.out.println(n+": "+minn);
        memo.put(n,minn);
        //System.out.println(memo.get(n));
        return minn;
    }
    public static void main(String[] args){
        System.out.println(bestSum(7,new int[]{2,1,3}));
    }
}

这两个代码片段之间的唯一区别是 int[] 以及 ArrayList<Integer> 但一个有效,另一个无效。我想知道原因,谢谢。链接到youtube解释bestsum()

e37o9pze

e37o9pze1#

很容易被记忆化和动态编程所困扰,而忘记了传递引用和传递值。这里要记住的关键区别是 ArrayList 是通过引用传递的。
如果你调试一下
hashmap memo ,你可以看到 int[] 最多只能达到 3 ,而在arraylist hashmap中,大多数值的大小为 7 我也遇到了类似的问题:强制转换在嵌套列表对象类型上不起作用,并且返回空列表(list<list>)

相关问题