创新工场涂鸦移动

转眼…9月末了秋招进入了尾声依然没有互联网的offer,甚至面试都没有多少,好难啊。
分享两道涂鸦移动的笔试题。赶紧自己是A了但是没有被发起面试,请大佬看看有什么问题吧。

  1. 给定一个只包含小写字母的字符串,我们通过如下规则分割它:
    1.一个片段中包含的字符不允许出现在其他片段内。
    2.分割的片段数应尽可能的多。
    请实现一个函数,输出分割的片段。
    例如:输入aabbbacceddefgkifk 输出为 aabbba cc edde fgkifk
import java.util.*;

/**
 * @author scz
 * @version 1.0
 * @date 2019-09-03 16:02
 */
public class test011 {

    public static void main(String args[])
    {
        /**
         * 例如:输入aabbbacceddefgkifk 输出为 aabbba cc edde fgkifk
         * 如下分割
         * 0 5
         * 6 7
         * 8 11
         * 12 17
         */
        String test = "aabbbacceddefgkifk";
        Repetitive(test);
    }

    /**
     *  获取重复的字符串及其下标(每个重复字母的第一次出现的下标和最后一次出现的下标)
     * @param str
     * @return java.util.Map<java.lang.String,java.util.ArrayList<java.lang.Integer>>
     * @author scz
     * @date 2019-09-03 17:25
     */
    public static  int[][] Repetitive(String str){
        char[] cArray = str.toCharArray();
        // key存字母,value是个List存出现未知
        Map<String, ArrayList<Integer>> saveMap=new HashMap<String, ArrayList<Integer>>();
        for (int i = 0; i < cArray.length; i++) {
            if(cArray[i] != '1')//设置一个不可能出现的值
            {
                //记录该字母
                String id = String.valueOf(cArray[i]);

                //创建list,用于存放字母所在的下标位置
                ArrayList<Integer> list=new ArrayList<Integer>();
                list.add(i); //记录该字母出现的第一个位置
                for (int j = i + 1; j < cArray.length; j++)
                {
                    //遍历数组,查找与cArray[i]相同的值并记录下标
                    if(cArray[i] == cArray[j])
                    {
                        list.add(j);
                        cArray[j] = '1';
                    }
                }
                //通过key-value将该字母和出现的位置put进map
                saveMap.put(id, list);
            }
        }

        // 获取saveMap中的key值,即出现的字母个数
        Set<String> idSet=saveMap.keySet();
        int[][] ints = new int[idSet.size()][2];
        int i = 0;
        for(String id:idSet) {
            //通过key获取其value
            int num = saveMap.get(id).size();
            if (num > 1){
                System.out.println(id+"数量为" + num);
                int first = saveMap.get(id).get(0);
                int end = saveMap.get(id).get(num - 1);
                ints[i][0] = first;
                ints[i][1] = end;
                System.out.println(id+" -->"+first+" "+end);
            }
            i++;
        }
        System.out.println(ints.length);
        return ints;
    }

    /**
     * 整理二维数组
     * @param ints
     * @return int[][]
     * @author scz
     * @date 2019-09-03 17:38
     */
    private static int[][] reget(int[][] ints){
        for (int i = 0; i < ints.length; i++) {
            //int[i][0]
        }
        return null;
    }

}

2.王师傅是一名卸货工人,现在有n个货物,由于王师傅一次可以同时卸2个货物,所以决定今天先卸其中的2m个货物。每次卸货物消耗的体力值的计算方式为,假如2个货物的质量分别为x和y,则消耗的体力值为 。现给出n个货物分别的质量,求王师傅卸完2m个货物后消耗的体力值最少是多少。

这个做的比较就,最后用的方差的性质才做出来。

/**
 * @author scz
 * @version 1.0
 */
public class test02 {
    /**
     * 选做)王师傅是一名卸货工人,现在有n个货物,由于王师傅一次可以同时卸2个货物,所以决定今天先卸其中的2*m个货物。
     * 每次卸货物消耗的体力值的计算方式为,假如2个货物的质量分别为x和y,则消耗的体力值为 (x-y)^4。
     * 现给出n个货物分别的质量,求王师傅卸完2*m个货物后消耗的体力值最少是多少。
     */

    public static void main(String[] args) {
        int[] nums = {1,1,3,3,4,6,26};
        int m = 3;
        List<int[]> selArray = selBetween(nums, m);
        select(selArray, selArray.size(), m);
    }

    /**
     *
     * @param nums
     * @param m
     * @return java.util.List<int[]>
     * @author scz
     * @date 2019-09-05 09:37
     */
    public static List<int[]> selBetween(int[] nums,int m){
        int num = 0;
        int index = m * 2;
        Arrays.sort(nums);
        List<int[]> list = new ArrayList<int[]>();
        List<Integer> minList = new ArrayList<Integer>();
        if(nums.length > index){
            //这部分找最值
            for(int i = 0; i < (nums.length - index + 1); i++){
                minList.add((nums[i+index-1] - nums[i]));
            }
            num = Collections.min(minList);
            // System.out.println(num);
            //这部分存数组
            for(int i = 0; i < (nums.length - index + 1); i++){
                if(num == (nums[i+index-1] - nums[i])){
                    int[] copy = new int[index];
                    for(int j = 0; j < index; j++){
                        copy[j] = nums[j+i];
                    }
                    list.add(copy);
                }
            }
        }else if(nums.length < index){
            for(int i = 0; i <nums.length; i++){
                nums[i] = 0;
            }
            System.out.println("输入的抽取数字大于集合内存在数字!数组清空!!!!");
            list.add(nums);
        }else{
            System.out.println("抽取与容量相等,返回原数组!!!!");
            list.add(nums);
        }
        return list;
    }

    /**
     *
     * @param list
     * @param size
     * @param m
     * @return void
     * @author scz
     */
    public static  void select(List<int[]> list, int size, int m){
        List<Integer> numslist = new ArrayList<Integer>();
        int index = m * 2;
        int number = 0;
        if(list.size() > 1){
            for(int[] i:list){
                int num = 0;
                for(int j = 0; j < index; j+=2){
                    num += (i[j+1] - i[j]);
                }
                numslist.add(num);
            }
            int min = Collections.min(numslist);

            for(int i = 0; i < numslist.size(); i++){
                if(numslist.get(i) == min){
                    number = i;
                }
            }
        }
        // System.out.println("最省力搬物规则如下:");
        double sum = 0;
        for(int j = 0; j < index; j+=2){
            double reduce = list.get(number)[j]-list.get(number)[j+1];
            reduce = Math.pow(reduce,4);
            sum = reduce + sum;
            // System.out.print(" 【 "+list.get(number)[j]+" , "+list.get(number)[j+1]+" 】 ");
        }
        System.out.println(sum);
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值