阿里笔试题-猴子摘桃子

来源:互联网 发布:耳机音量放大器软件 编辑:程序博客网 时间:2024/06/10 19:21

题目:
小猴子下山,沿着下山的路由一排桃树,每棵树都结了一些桃子。
小猴子想摘桃子,但是有一些条件需要遵守,小猴子只能沿着下山的方向走,
不能回头,每棵树最多摘一个,而且一旦摘了一棵树的桃子,就不能再摘比这棵树结的桃子少的(个人觉得等于的应该是算的)树上的桃子了,那么小猴子最多能摘几个桃子呢?举例说明,比如有5课树,分别结了10,4,5,12,8颗桃子,
那么小猴子最多能摘3颗桃子,来自于结了4,5,8颗桃子的树。

如:
{10,4,5,12,8}
结果:
3

思路有两个:
1.相当于就是找最小的LST,我们这里将每次插入后形成的队列用PriorityQueue表示,每次将插入时候,就查看以前已经有的数据,如果比其中最大的值大,那么新建一个队列并合入当前这个队列和这个数据。最后最长的队列长度就是结果

2.上面的空间中,很多队列数据重复性较大,这里采用一个跟数组相同大小的数组,里面存放,比当前数据小的数据所在的索引,这里只存放相邻的。比如2,5,12,检索时候如果是12从前检索,那么12会拿到2和5的索引,走到5的时候,如果发现5也有2的索引,那么需要将12中2的索引去掉。

思路一:
对于思路一中间的临时队列,我们将最后的结果展开
索引 含有的值
0 10
1 4
2 5,4
3 5
4 12,10
5 12,4
6 12,5,4
7 12,5
8 12
9 8,4
10 8,5,4
11 8,5
12 8

其中最长的个数为3,因为这里只要求的是个数

思路二:
中间的临界点表
索引 含有的值
0 []
1 []
2 [1]
3 [0,2]
4 [2]

这里面根据递归方式查找最长为3

思路一代码:

import java.util.*;import java.util.concurrent.CopyOnWriteArrayList;/** * 小猴子下山,沿着下山的路由一排桃树,每棵树都结了一些桃子。 * 小猴子想摘桃子,但是有一些条件需要遵守,小猴子只能沿着下山的方向走, * 不能回头,每棵树最多摘一个,而且一旦摘了一棵树的桃子,就不能再摘比这棵树结的桃子少的树上的桃子了, * 那么小猴子最多能摘几个桃子呢?举例说明,比如有5课树,分别结了10,4,5,12,8颗桃子, * 那么小猴子最多能摘3颗桃子,来自于结了4,5,8颗桃子的树。 * * 当前思路: * 将每次加入数据后得到的长序列全部罗列出来 * * @author zhouzhenyong * @since 2017/8/31. */public class Exam_houzi {    public static void main(String[] args) {        int[] data = {10,4,5,12,8};        Exam_houzi examSlipe = new Exam_houzi();        show(examSlipe.resolve(data));    }    private List<PriorityQueue<Integer>> queues = new CopyOnWriteArrayList<PriorityQueue<Integer>>();    private List<Integer> resutList = new ArrayList();    public int resolve(int[] datas) {        //获取数据        for (int i = 0; i < datas.length; i++) {            insertData(datas[i]);        }        //获取最后的最大值        return getMaxLength();    }    /**     * 返回队列表中的最大长度的队列     * @return     */    public int getMaxLength(){        int maxLength = 0;        for(ListIterator<PriorityQueue<Integer>> listIterator = queues.listIterator();listIterator.hasNext();){            PriorityQueue<Integer> p = listIterator.next();            if(p.size() != 0 && maxLength < p.size()){                maxLength = p.size();            }        }        return maxLength;    }    /**     * 将数据录入到最长队列存储表中     * @param data     */    public void insertData(int data){        for(ListIterator<PriorityQueue<Integer>> listIterator = queues.listIterator();listIterator.hasNext();){            PriorityQueue<Integer> p = listIterator.next();            if(p.size() != 0 && data >= p.peek()){                addData(p, data);            }        }        addData(data);    }    public void addData(int data){        PriorityQueue priorityQueue = createQueue();        priorityQueue.add(data);        queues.add(priorityQueue);    }    public void addData(PriorityQueue oldPriorityQueue, int currentData){        PriorityQueue priorityQueue = createQueue();        priorityQueue.addAll(oldPriorityQueue);        priorityQueue.add(currentData);        queues.add(priorityQueue);    }    /**     * 创建一个降序的队列     * @return     */    public PriorityQueue createQueue(){        return new PriorityQueue<Integer>(new Comparator<Integer>() {            public int compare(Integer o1, Integer o2) {                return o2.compareTo(o1);            }        });    }    public static void show(Object data) {        System.out.println(data);    }}

思路二代码:

import java.util.*;/** * 小猴子下山,沿着下山的路由一排桃树,每棵树都结了一些桃子。 * 小猴子想摘桃子,但是有一些条件需要遵守,小猴子只能沿着下山的方向走, * 不能回头,每棵树最多摘一个,而且一旦摘了一棵树的桃子,就不能再摘比这棵树结的桃子少的树上的桃子了, * 那么小猴子最多能摘几个桃子呢?举例说明,比如有5课树,分别结了10,4,5,12,8颗桃子, * 那么小猴子最多能摘3颗桃子,来自于结了4,5,8颗桃子的树。 * * 思路: * 在每个数组的其中一个元素保存比他小的那个索引,只保存一个 * * @author zhouzhenyong * @since 2017/9/5. */public class Exam_houzi_2 {    //用于存储每个数据对应的比他小的索引,与源数据索引对应    private Set<Integer>[] indexSet;    public static void main(String[] args) {        int[] data = {10,4,5,12,8};        Exam_houzi_2 examSlipe = new Exam_houzi_2();        show(examSlipe.resolve(data));    }    /**     * 首先配置本地数据     * @param datas     */    public void configLocal(int[] datas){        indexSet = new HashSet[datas.length];        indexSet[0]=new HashSet();    }    /**     *     * @param datas     * @return     */    public int resolve(int[] datas){        //配置本地数据        configLocal(datas);        //处理数据        parseData(datas);        return maxLength(datas);    }    /**     * 采用递归的方式获取最长的长度     * @return     */    public int maxLength(int[] datas){        int maxLenght = 0;        for(int i=0;i<datas.length;i++){            int length = lengthOfIndex(i);            if(maxLenght < length){                maxLenght = length;            }        }        return maxLenght;    }    /**     * 采用递归的方式获取每一个索引的长度     * @param index     * @return     */    public int lengthOfIndex(int index){        if(indexSet[index].size() == 0){            return 1;        }        int length = 0;        for(int indexOther: indexSet[index]){            int tem = lengthOfIndex(indexOther);            if(length < tem){                length = tem;            }        }        return length+1;    }    /**     * 采用一种保存比当前数据小的索引的方式,存储当前数据     * @param datas     */    public void parseData(int[] datas){        for(int index=0;index < datas.length; index++){            Set<Integer> set = new HashSet();            for(int indexJ = 0;indexJ <index;indexJ++){                if(datas[indexJ] <= datas[index]){                    set.add(indexJ);                    if(indexSet[indexJ] != null) {                        set.removeAll(indexSet[indexJ]);                    }                }            }            indexSet[index]=set;        }    }    public static void show(Object data) {        System.out.println(data);    }}