阿里巴巴的一个笔试题

来源:互联网 发布:美国宏观经济数据 编辑:程序博客网 时间:2024/05/01 04:17

看到一个网友贴的一个阿里巴巴的问题和对应的解决方式,觉得有点复杂,想在下面评论贴下代码,但是又太长了,就贴在这里了
源网友链接:
http://blog.csdn.net/shenzhuan7/article/details/62881076#java
题目是这样子的:给我们一个数组,比如说[113,215,221];那么这个数组是表示的一个二叉树,是这样表示的,每一个3位数,百位上的值表示这个节点在第几层,十位上的数表示在这一层的第几个位置,个位就这个节点的值了,比如上面的数组表示的二叉树就是:
3
/ \
5 1
然后要求我们求出叶子节点所在路径的节点之和:(3->5)这是一个叶子节点的路径,(3->1)这是另一个叶子节点的路径,就是求(3+5)+(3+1)=12。然后还告诉你最多有4层,我感觉这个条件一下降低了难度。

网友的思路是把给定的数组转化成一般的二叉树表示的,然再求叶子的路径之和的。

我的思路是:
按照叶子节点向上加这种,我们可以反过来看,每个节点被加了多少次,对非根节点,他有多少个叶子节点就会被加多少次,那么按照这样来理解,上面的问题就可以转化成当前节点的值乘以当前节点拥有的叶子个数,对所有的节点都遍历一遍即可。

其中叶子节点对应的叶子个数为1,非叶子节点对应的个数是它下面的叶子个数。上面就可以转化为如下:
(3+5)+(3+1)= 3*2+5*1+1*1 = 12
这样的话,上面的这种就可以转换成通过递归的方式来搞,这样就会简单一些,其中源数组的数据我这里通过一个二维数组来进行转化。
直接贴代码

public class Exam_shuzu {    private int[][] listData = new int[5][9];       //因为限制了最多的层数,因此可以开辟这样一个二维数组    private int maxLevel = 0;    public static void main(String[] args){//      int[] list = {113,215,221};                   //结果12//      int[] list = {115,212};                          //结果7        int[] list = {115,212,221,314,329,333};  //结果36        Exam_shuzu examSlipe = new Exam_shuzu();        System.out.println(examSlipe.resolve(list));    }    /**     * @param list     * @return     */    public int resolve(int[] list){        //首先配置本地相关数据        configLocalData(list);        //计算总的数据        return getWeigth(1, 1);    }    /**     * 配置本地的二维数组数据,和统计当前的层数     * @param list     */    private void configLocalData(int[] list){        int maxLevel = getMaxLevel(list);        for(int index = 1;index < maxLevel+1;index++){            for(int num:list) {                int first = getFist(num);                if (index == first){                    listData[index][getMid(num)] = getLast(num);                }            }        }    }    public int getMaxLevel(int[] list){        int level=0;        for(int num:list){            int first = getFist(num);            if(level < first){                level = first;            }        }        this.maxLevel = level;        return level;    }    public int getFist(int data){        return data/100;    }    public int getMid(int data){        return (data/10)%10;    }    public int getLast(int data){        return data%10;    }    /**     * 当前值和叶子节点加权后的值,通过递归的方式来搞     */    public int getWeigth(int level, int index){        if(level >= this.maxLevel){            return listData[level][index];        }        return listData[level][index] * numOfLeaf(level, index) +getWeigth(level+1, 2*index-1)+getWeigth(level+1, 2*index);    }    /**     * 节点的叶子个数,用递归的方式     * @return     */    public int numOfLeaf(int level, int index){        if(level >= this.maxLevel){            return (listData[level][index] != 0)?1:0;        }        return numOfLeaf(level+1, 2*index -1)+ numOfLeaf(level+1, 2*index);    }}

自己也构造了一个稍微复杂点的例子:
5
/ \
2 1
/ \ /
4 9 3
对应的数组为:{115,212,221,314,329,333}
结果:
(4+2+5)+(9+2+5)+(3+1+5)= 5*3+2*2+1*1+4+9+3 = 36

读者也可以看看是否还有其他的更好的方式

原创粉丝点击