LeetCode 第 142 场周赛 【大样本统计】【拼车】【山脉数组中查找目标值】【花括号展开 II】

1093. 大样本统计

我们对 0 到 255 之间的整数进行采样,并将结果存储在数组 count 中:count[k] 就是整数 k 的采样个数。

我们以 浮点数 数组的形式,分别返回样本的最小值、最大值、平均值、中位数和众数。其中,众数是保证唯一的。

我们先来回顾一下中位数的知识:

  • 如果样本中的元素有序,并且元素数量为奇数时,中位数为最中间的那个元素;
  • 如果样本中的元素有序,并且元素数量为偶数时,中位数为中间的两个元素的平均值。

示例 1:

输入:count = [0,1,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出:[1.00000,3.00000,2.37500,2.50000,3.00000]

示例 2:

输入:count = [0,4,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出:[1.00000,4.00000,2.18182,2.00000,1.00000]

提示:

count.length == 256
1 <= sum(count) <= 10^9
计数表示的众数是唯一的
答案与真实值误差在 10^-5 以内就会被视为正确答案
	//最小值、最大值、平均值、中位数和众数
    public static double[] sampleStats(int[] count) {
        //某数出现的最大次数
        int maxModeCount = Integer.MIN_VALUE;
        //数总和
        double sum = 0.0;
        //记录数的总个数
        int countNum = 0;
        //结果数组
        double[] res = new double[5];
        //中位数的下标
        int midIndex = count[0];
        boolean flag = true;
        for (int i = 0; i < count.length; i++) {
            //求最小值,从左至右第一次出现的数,即第一次array[i]!=0时候
            //求最大值,从左至右最后一次出现的数,即最后一次array[i]!=0时候(每次更新即可)
            if (count[i] != 0) {
                if (flag) {
                    flag = false;
                    res[0] = (double) i;
                }
                res[1] = (double) i;
            }
            //求众数,即求max(array[i]),那么i就是众数
            if (count[i] > maxModeCount) {
                maxModeCount = count[i];
                res[4] = (double) i;
            }
            //记录所有数出现的次数
            countNum += count[i];
            //求和
            sum += count[i] * i;
            //中位数在的位置
            midIndex = countNum / 2;
        }
        res[2] = sum / countNum;
        //元素数量为偶数时,中位数为中间的两个元素的平均值,所以需要找到已知中位数的下一个数
        double midNum = 0;
        double midNumNext = 0;
        //再次遍历求中位数
        int cnt = 0;
        for (int i = 0; i < count.length; i++) {
            cnt += count[i];
            //找到了
            if (cnt >= midIndex) {
                //如果刚好等于,那么就继续遍历找到下一个数即可
                if (cnt == midIndex) {
                    midNum = i;
                    for (int j = i + 1; j < count.length; j++) {
                        if (count[j] != 0) {
                            midNumNext = j;
                            break;
                        }
                    }
                    break;
                } else {//cnt>midIndex
                    midNum = i;
                    midNumNext = i;
                    break;
                }
            }
        }
        //偶数
        if (countNum % 2 == 0) {
            res[3] = (midNum + midNumNext) / 2;
        } else {
            res[3] = midNum;
        }
        return res;
    }

1094. 拼车

假设你是一位顺风车司机,车上最初有 capacity 个空座位可以用来载客。由于道路的限制,车 只能 向一个方向行驶(也就是说,不允许掉头或改变方向,你可以将其想象为一个向量)。

这儿有一份行程计划表 trips[][],其中 trips[i] = [num_passengers, start_location, end_location] 包含了你的第 i 次行程信息:

  • 必须接送的乘客数量;
  • 乘客的上车地点;
  • 以及乘客的下车地点。

这些给出的地点位置是从你的 初始 出发位置向前行驶到这些地点所需的距离(它们一定在你的行驶方向上)。

请你根据给出的行程计划表和车子的座位数,来判断你的车是否可以顺利完成接送所用乘客的任务(当且仅当你可以在所有给定的行程中接送所有乘客时,返回 true,否则请返回 false)。

示例 1:

输入:trips = [[2,1,5],[3,3,7]], capacity = 4
输出:false

示例 2:

输入:trips = [[2,1,5],[3,3,7]], capacity = 5
输出:true

示例 3:

输入:trips = [[2,1,5],[3,5,7]], capacity = 3
输出:true

示例 4:

输入:trips = [[3,2,7],[3,7,9],[8,3,9]], capacity = 11
输出:true
	public static boolean carPooling(int[][] trips, int capacity) {
        if(trips.length<=0){
            return true;//false?
        }
        if(trips.length==1&&trips[0][0]<=capacity){
            return true;
        }else if(trips.length==1){//trips[0][0]>capacity
            return false;
        }
        //trips.length>1
        //排序,以所有行程的上车地点来升序排序
        Arrays.sort(trips, new Comparator<int[]>() {
            public int compare(int[] arr1, int[] arr2) {
                return arr1[1] - arr2[1];			//按照区间第二个数大小!!!!!!
            }
        });
        for(int[] t:trips){
            for(int a:t){
                System.out.print(" "+a);
            }
            System.out.println();
        }
        //双向队列来辅助操作,队列里面维护一个,从左到右依次先下车的序列,
        LinkedList <int[]> list=new LinkedList<>();
        //第一个入队
        list.add(trips[0]);
        int nowCapacity=trips[0][0];
        for(int i=1;i<trips.length;i++){
            //遍历list,如果list左边乘客的下车点已经<=现在乘客的上车点,那么下车(出队)
            while(list.size()>0&&list.getFirst()[2]<=trips[i][1]){
                //左边出队
                int []tmp=list.pollFirst();
                //更新容量
                nowCapacity-=tmp[0];
            }
            list.add(trips[i]);
            Collections.sort(list, new Comparator<int[]>() {
                public int compare(int[] arr1, int[] arr2) {
                    return arr1[2] - arr2[2];			//按照区间第3个数大小!!!!!!
                }
            });
            nowCapacity+=trips[i][0];   //13
            //查看当前是否超载
            if(nowCapacity>capacity){
                System.out.println(nowCapacity);
                return false;
            }
        }
        return true;
    }

另一种解法:

	public boolean carPooling02(int[][] trips, int capacity) {
        TreeMap<Integer,Integer> tmap = new TreeMap<>();
        for(int i=0;i<trips.length;++i){
            Integer startNum = tmap.get(trips[i][1]);
            Integer endNum = tmap.get(trips[i][2]);
            if(startNum == null)
                startNum =0;
            if(endNum == null)
                endNum=0;
            startNum=startNum+trips[i][0];
            endNum=endNum-trips[i][0];
            tmap.put(trips[i][1],startNum);
            tmap.put(trips[i][2],endNum);
        }
        int carry = 0;
        for(Integer p:tmap.keySet()){
            carry+=tmap.get(p);
            if(carry>capacity)
                return false;
        }
        return true;
    }

1095. 山脉数组中查找目标值

(这是一个 交互式问题 )

给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。

如果不存在这样的下标 index,就请返回 -1。

所谓山脉数组,即数组 A 假如是一个山脉数组的话,需要满足如下条件:

首先,A.length >= 3

其次,在 0 < i < A.length - 1 条件下,存在 i 使得:

  • A[0] < A[1] < … A[i-1] < A[i]
  • A[i] > A[i+1] > … > A[A.length - 1]

你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据:

  • MountainArray.get(k) - 会返回数组中索引为k 的元素(下标从 0 开始)
  • MountainArray.length() - 会返回该数组的长度

示例 1:

输入:array = [1,2,3,4,5,3,1], target = 3
输出:2
解释:3 在数组中出现了两次,下标分别为 2 和 5,我们返回最小的下标 2。

原题地址:https://leetcode-cn.com/contest/weekly-contest-142/problems/find-in-mountain-array/

引用答案:

public int findInMountainArray(int target, MountainArray mountainArr) {
        int len=mountainArr.length(),idx=-1;
        int left=0,right=len-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(mid==0){
                left=mid+1;
                continue;
            }
            if(mid==len-1){
                right=mid-1;
                continue;
            }
            int l=mountainArr.get(mid-1),r=mountainArr.get(mid+1),cur=mountainArr.get(mid);
            if(l<cur&&r<cur){
                idx=mid;
                break;
            }else if(l>cur&&cur>r) {
                right = mid - 1;
            }else{
                left=mid+1;
            }
        }
        left=0;
        right=idx;
        while(left<=right){
            int mid=(left+right)/2;
            int cur=mountainArr.get(mid);
            if(cur==target){
                return mid;
            }else if(cur>target) {
                right = mid - 1;
            }else{
                left=mid+1;
            }
        }
        left=idx+1;
        right=len-1;
        while(left<=right){
            int mid=(left+right)/2;
            int cur=mountainArr.get(mid);
            if(cur==target){
                return mid;
            }else if(cur<target) {
                right = mid - 1;
            }else{
                left=mid+1;
            }
        }
        return -1;
    }

1096. 花括号展开 II

如果你熟悉 Shell 编程,那么一定了解过花括号展开,它可以用来生成任意字符串。

花括号展开的表达式可以看作一个由 花括号、逗号 和 小写英文字母 组成的字符串,定义下面几条语法规则:

  • 如果只给出单一的元素 x,那么表达式表示的字符串就只有 “x”。
    例如,表达式 {a} 表示字符串 “a”。
    而表达式 {ab} 就表示字符串 “ab”。
  • 当两个或多个表达式并列,以逗号分隔时,我们取这些表达式中元素的并集。
    例如,表达式 {a,b,c} 表示字符串 “a”,“b”,“c”。
    而表达式 {a,b},{b,c} 也可以表示字符串 “a”,“b”,“c”。
  • 要是两个或多个表达式相接,中间没有隔开时,我们从这些表达式中各取一个元素依次连接形成字符串。
    例如,表达式 {a,b}{c,d} 表示字符串 “ac”,“ad”,“bc”,“bd”。
  • 表达式之间允许嵌套,单一元素与表达式的连接也是允许的。
    例如,表达式 a{b,c,d} 表示字符串 “ab”,“ac”,"ad"​​​​​​。
    例如,表达式 {a{b,c}}{{d,e}f{g,h}} 可以代换为 {ab,ac}{dfg,dfh,efg,efh},表示字符串 “abdfg”, “abdfh”, “abefg”, “abefh”, “acdfg”, “acdfh”, “acefg”, “acefh”。
    给出表示基于给定语法规则的表达式 expression,返回它所表示的所有字符串组成的有序列表。

原题地址:https://leetcode-cn.com/contest/weekly-contest-142/problems/brace-expansion-ii/

引用答案:

	class Node {
        List<String> res = new ArrayList<>();
        int idx;
    }

    Node solve(String str, int start) {
        Set<String> res = new HashSet<>();

        res.add("");
        StringBuilder sb = new StringBuilder();
        for (int i = start; i < str.length(); i++) {
            if (str.charAt(i) == ' ') continue;
            if (str.charAt(i) == '{') {
                if (sb.length() > 0) {
                    Set<String> nres = new HashSet<>();
                    for (String s : res) {
                        nres.add(s + sb.toString());
                    }
                    res = nres;
                    sb = new StringBuilder();
                }
                Node ans = solve(str, i + 1);
                Set<String> nres = new HashSet<>();
                for (String s : res)
                    for (String s2 : ans.res) {
                        nres.add(s + s2);
                    }
                res = nres;
                i = ans.idx;
            } else if (str.charAt(i) == ',') {
                if (sb.length() > 0) {
                    Set<String> nres = new HashSet<>();
                    for (String s : res) {
                        nres.add(s + sb.toString());
                    }
                    res = nres;
                    sb = new StringBuilder();
                }
                Node ans = solve(str, i + 1);
                res.addAll(ans.res);

                ans.res.clear();
                ans.res.addAll(res);
                return ans;
            } else if (str.charAt(i) == '}') {
                if (sb.length() > 0) {
                    Set<String> nres = new HashSet<>();
                    for (String s : res) {
                        nres.add(s + sb.toString());
                    }
                    res = nres;
                    sb = new StringBuilder();
                }
                Node ans = new Node();
                ans.res.addAll(res);
                ans.idx = i;
                return ans;
            } else {
                sb.append(str.charAt(i));
            }
        }
        if (sb.length() > 0) {
            Set<String> nres = new HashSet<>();
            for (String s : res) {
                nres.add(s + sb.toString());
            }
            res = nres;
            sb = new StringBuilder();
        }
        Node ans = new Node();
        ans.res.addAll(res);
        ans.idx = str.length();
        return ans;
    }

    public List<String> braceExpansionII(String expression) {
        Node res = solve(expression, 0);
        Collections.sort(res.res);
        return res.res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值