最优二叉树||

最优二叉树II

http://www.nowcoder.com/questionTerminal/0d939e874a004f449a370aca1346dd5c

图片说明
图片说明

import java.io.*;
public class Main{
    //每个节点选择对应的开销   
    static int[][][] mem;
    static int[] weight;
    static int n;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine().trim());
        String[] str = br.readLine().split(" ");
        weight = new int[n];
        for(int i = 0; i < n; i++){
            weight[i] = Integer.parseInt(str[i]);
        }
        //mem[l][r][k]表示以weight[l:r]为子节点,以weight[k]为根节点的树开
        mem = new int[n][n][n];
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                for(int k = 0; k < n; k++){
                    mem[i][j][k] = -1;
                }
            }
        }
        System.out.println(recur(0, n - 1, -1));
    }

    public static int recur(int left, int right, int root){

        if(left > right) return 0;
        //左右子树和根节点这个结构已经被记录过的情况下,直接返回,减少搜索时间
        if(root >= 0 && mem[left][right][root] != -1) return mem[left][right][root];
        int cost = Integer.MAX_VALUE;
        int leftCost = 0, rightCost = 0;
        //在这个数组中按照中序遍历的格式去寻找
        for(int i = left; i <= right; i++){
            //递归下去 每次都会在区间寻找开销比较小的左右子树
            leftCost = recur(left, i - 1, i);
            rightCost = recur(i + 1, right, i);
            cost = Math.min(cost, leftCost + rightCost + weight[i] * (root != -1 ? weight[root] : 0));
        }
        //记录
        if(root >= 0) mem[left][right][root] = cost;
        return cost;
    }
}

有三点值得学习:

  • 采用输入流来接收,比较方便
  • 采用备忘录数组,来记录每个选择结构节点的开销,减少了递归搜索的时间,直接返回结果,也需要在这个递归中记录结果
  • 全程使用数组去模拟二叉树,采用分治思想,去递归
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务