当前位置: 首页 > news >正文

给定一个数组arr,长度为N且每个值都是正数,代表N个人的体重。再给定一个正数 limit,代表一艘船的载重。

问题描述:

        给定一个数组arr,长度为N且每个值都是正数,代表N个人的体重。再给定一个正数 limit,代表一艘船的载重。

        以下是坐船规则:

  1. 每艘船最多只能做两人。
  2. 乘客 的体重和不能超过limit。

        返回如果同时让这N个人过河最少需要几条船。 

思想:

        首先把整个数组进行排序,若数组中出现大于limit的数字,则无法过河,直接返回-1。

普遍情况算法流程:

1.找到小于等于limit一半的数位置L,另一半指针为R= L+1。

2.从L开始和R位置的数进行配对。

        2.1 如果L位置的数和R位置上的数加起来大于limit,那么R位置保持不变,L位置向左移动一位,原本L位置的数字为X类型数字。

        2.2 如果L位置的数和R位置上的数加起来小于等于limit,那么移动R位置,查看R右半部分宫有几个数字和L位置数字匹配满足条件。我们就找到了一批匹配的数字,记录右部分移动了几位,左半部分也相应的移动几位。这类型的人员用√表示。

        2.3 在2.2中若右半部分找不到匹配的数字,则L向左移动一位,原本L位置的数字为X类型数字。

        2.4 最后结果可能分为两种情况:左侧先匹配完和右侧先匹配完。当左侧先匹配完时,右侧剩下的数字每个人一条船。当右侧先匹配完时,左侧剩下的每个人都是X类型。

3. X类型人员两人乘一艘船,√号类型人员左半部分和右半部分搭配乘一条船,右侧剩下的人员每个人乘一条船。最后的结果是这三类人员相加和。

代码:

    public static int minBost(int[] arr, int limit) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        int N = arr.length;

        if (arr[N - 1] > limit) {
            return -1;
        }
        int lessR = -1;
        //所有人的体重都不超过limit
        // <= limit/2  最右的位置
        for (int i = N - 1; i >= 0; i--) {
            if (arr[i] <= (limit / 2)) {
                lessR = i;
                break;
            }
        }
        if (lessR == -1) {
            return N;
        }

        int L = lessR;
        int R = lessR + 1;
        int noUsed = 0;//画X的数量统计
        while (L >= 0) {
            int solved = 0;//此时的[L],让R画过了几个数
            while (R < N && arr[L] + arr[R] <= limit) {
                R++;
                solved++;
            }
            //R来到不达标的位置
            if (solved == 0) {
                noUsed++;
                L--;
            } else {//此时的[L],让R画过的solved个数
                L = Math.max(-1, L - solved);
            }
        }
        //左半区总个数  <=limit/2的区域
        int all = lessR + 1;
        //画对号的量
        int used = all - noUsed;
        // >limit/2区域中,没搞定的数量
        int moreUnsolved = (N - all) - used;
        return used + ((noUsed + 1) >> 1) + moreUnsolved;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5};
        int weight = 6;
        System.out.println(minBost(arr, weight));
    }

相关文章:

  • 网络应用层之(6)L2TP协议详解
  • RMQ从入门到精通
  • 服务器数据恢复—服务器重装系统导致XFS分区丢失的数据恢复案例
  • Co-assistant Networks for Label Correction论文速读
  • 『FPGA通信接口』DDR(3)DDR3颗粒读写测试
  • 吐槽3家知名的AI智能体
  • 【二】【SQL】去重表数据及分组聚合查询
  • 【Elasticsearch索引】Rollover滚动、Shrink收缩、Split拆分索引
  • npm run dev和npm run serve两个命令的区别
  • 【蓝桥杯】快读|min和max值的设置|小明和完美序列|​顺子日期​|星期计算|山
  • Spring Boot项目误将Integer类型写成int来进行传参
  • 全面升级!Apache HugeGraph 1.2.0版本发布
  • 【大道模式】状态模式 - State Pattern(审核状态流转)
  • 协议-序列化-http-Cookie-Session-https
  • 数据结构—Map集合
  • SpringMVC对消息转换器的处理相关
  • Linux-文件压缩解压
  • [附源码]计算机毕业设计JAVA医药管理系统
  • [附源码]计算机毕业设计基于SpringBoot+Vue的健身房会员系统的设计与实现
  • 9 特色聚类
  • python中的集合详解
  • pringboot面向爱宠人群的宠物资讯系统36as8计算机毕业设计-课程设计-期末作业-毕设程序代做
  • Flink系列之Flink中StateBackend深入剖析和应用
  • Java可变参数和集合工具类Collections的详细介绍
  • 网站构建初级教程
  • 项目管理逻辑:老板为什么赔钱的项目也做?为什么害怕你闲着?
  • Spring Boot 框架整合 MyBatis 连接数据库,详细说明
  • MySQL主从同步
  • 微服务自动化【Docker-Compose】
  • 在Postgres中分页的五种方法,从基本到异国情调
  • 工作经历分享
  • 堆(二叉堆)-优先队列-数据结构和算法(Java)