leetcode 17

在这里插入图片描述

import java.util.*;

public class BuildingOutline {
    public static class Op{
        public int x;
        public boolean isAdd;//true为+
        public int h;
        public Op(int x,boolean isAdd,int h)
        {
            this.x = x;
            this.isAdd = isAdd;
            this.h = h;
        }
    }

    public static class NodeComparator implements Comparator<Op>{

        @Override
        public int compare(Op o1, Op o2) {
            if(o1.x != o2.x){
                return o1.x - o2.x;
            }
            if(o1.isAdd != o2.isAdd){
                return o1.isAdd ? -1:1;
            }
            return 0;
        }
    }

    public static List<List<Integer>> buildOutlin(int[][] matrix){
        int N = matrix.length;

        Op[] ops= new Op[matrix.length * 2];
        for (int i = 0; i < matrix.length; i++) {
            ops[i*2] = new Op(matrix[i][0],true,matrix[i][2]);
            ops[i*2+1] = new Op(matrix[i][1],false,matrix[i][2]);
        }
        Arrays.sort(ops,new NodeComparator());

//		这个有序表可以选出最高的高度, 
        TreeMap<Integer,Integer> mapHeightTimes = new TreeMap<>();
        //x左边从小到大收集 
        TreeMap<Integer,Integer> mapXHeight = new TreeMap<>();
        for (int i = 0; i < ops.length; i++) {
            if(ops[i].isAdd){//高度加的优先操作,防止单个纸片,[3,3,2]
                if(!mapHeightTimes.containsKey(ops[i].h)){
                    mapHeightTimes.put(ops[i].h,1);
                }else{
                    mapHeightTimes.put(ops[i].h,mapHeightTimes.get(ops[i].h)+1);
                }
            }else{
                if(mapHeightTimes.get(ops[i].h) == 1){
                    mapHeightTimes.remove(ops[i].h);
                }else{
                    mapHeightTimes.put(ops[i].h,mapHeightTimes.get(ops[i].h)-1);
                }
            }

            if(mapHeightTimes.isEmpty()){
                mapXHeight.put(ops[i].x,0);
            }else{
                mapXHeight.put(ops[i].x,mapHeightTimes.lastKey());
            }
        }
        List<List<Integer>> res = new ArrayList<>();
        int start = 0;
        int preHeight = 0;
        for(Map.Entry<Integer,Integer> entry:mapXHeight.entrySet()){
            int curX = entry.getKey();
            int curMaxHeight = entry.getValue();
            if(preHeight != curMaxHeight){
                if(preHeight != 0){
                    res.add(new ArrayList<>(Arrays.asList(start,curX,preHeight)));
                }
                start = curX;
                preHeight = curMaxHeight;
            }
        }
        return res;
    }
}

在这里插入图片描述

一个异或和不等于0的 先手赢,先手总能拿一个使得后手异或和等于0
在这里插入图片描述

import java.util.Arrays;

public class MinBoat {
    public static int minBoat(int[] arr, int limit){
        if(arr == null || arr.length == 0){
            return 0;
        }
        Arrays.sort(arr);
        if(arr[arr.length - 1]  > limit){
            return  -1;
        }

        int lessR = -1;
        for(int i = arr.length-1;i >= 0;i--){
            if(arr[i] <=(limit/2)){
                lessR = i;
                break;
            }
        }

        if(lessR == -1){
           return arr.length;
        }
        //从中间划分
        int L = lessR;//中间左边的指针
        int R = lessR + 1;//中间右边的指针
        int noUsed= 0; //画x的统计数量

        while(L >= 0){
            //同时防止右边提前使用完了
            int sloved = 0;//此时的L,让R画了几个数

            while (R < arr.length && arr[L] + arr[R] <= limit){
                R++;
                sloved++;
            }
            //上述完之后 R到了第一个不达标的位置
            if(sloved == 0){
                noUsed++;//X的个数增加
                L--;
            }else{
                L = Math.max(-1,L-sloved);//L来到对应解决过的位置
            }

        }
        int lessUsed = lessR + 1 - noUsed;//画对号的数量
        int moreUnsolved =  arr.length - lessR -1 - lessUsed;//>limt/2没有搞定的数量
        //(N+1)/2 相当于N/2向上取整 因为如果还剩下一个人也要坐船
        return lessUsed + (((noUsed)+1)>>1) + moreUnsolved;

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值