LeetCode2409——统计共同度过的日子数

news2024/12/25 19:32:19

在这里插入图片描述


博主的解法过于冗长,是一直对着不同的案例debug修改出来的,不建议学习。虽然提交成功了,但是自己最后都不知道写的是啥了哈哈哈。
在这里插入图片描述
在这里插入图片描述

package keepcoding.leetcode.leetcode2409;
/*Alice 和 Bob 计划分别去罗马开会。
        给你四个字符串 arriveAlice ,leaveAlice ,arriveBob 和 leaveBob 。
        Alice 会在日期 arriveAlice 到 leaveAlice 之间在城市里(日期为闭区间),
        而 Bob 在日期 arriveBob 到 leaveBob 之间在城市里(日期为闭区间)。每个字符串都包含 5 个字符,格式为 "MM-DD" ,对应着一个日期的月和日。
        请你返回 Alice和 Bob 同时在罗马的天数。
        你可以假设所有日期都在 同一个 自然年,而且 不是 闰年。每个月份的天数分别为:[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]*/
public class Result01 {
    public static void main(String[] args) {
        int days = countDaysTogether("08-12","08-26","08-26","10-25");
        System.out.println(days);
    }

    /*
    输入:arriveAlice = "08-15", leaveAlice = "08-18",
    arriveBob = "08-16", leaveBob = "08-19"
    输出:3
    解释:Alice 从 8 月 15 号到 8 月 18 号在罗马。Bob 从 8 月 16 号到 8 月 19 号在罗马,
    他们同时在罗马的日期为 8 月 16、17 和 18 号。所以答案为 3 。
    */
    public static int countDaysTogether(String arriveAlice, String leaveAlice, String arriveBob, String leaveBob) {

        String[] arriveAliceTimeArray = arriveAlice.split("-",2);
        String[] leaveAliceTimeArray = leaveAlice.split("-",2);
        String[] arriveBobTimeArray = arriveBob.split("-",2);
        String[] leaveBobTimeArray = leaveBob.split("-",2);

        int aliceArriveMonth = Integer.valueOf(arriveAliceTimeArray[0]);
        int aliceLeaveMonth = Integer.valueOf(leaveAliceTimeArray[0]);
        int aliceArriveDay = Integer.valueOf(arriveAliceTimeArray[1]);
        int aliceLeaveDay = Integer.valueOf(leaveAliceTimeArray[1]);
        int bobArriveMonth = Integer.valueOf(arriveBobTimeArray[0]);
        int bobLeaveMonth = Integer.valueOf(leaveBobTimeArray[0]);
        int bobArriveDay = Integer.valueOf(arriveBobTimeArray[1]);
        int bobLeaveDay = Integer.valueOf(leaveBobTimeArray[1]);

        if (aliceArriveDay==bobArriveDay && aliceArriveMonth==bobArriveMonth && aliceLeaveDay==bobLeaveDay && aliceLeaveMonth==bobLeaveMonth){
            if (aliceArriveDay==1 && aliceLeaveMonth==12){
                return 365;
            }else if (aliceArriveDay==28 && aliceArriveMonth==2 && aliceLeaveMonth==3){
                return 2;
            }
        }

        //alice和bob同一个月到
        if (aliceArriveMonth == bobArriveMonth) {
            //同一个月走
            if (aliceLeaveMonth==bobLeaveMonth){
                if (aliceArriveDay > bobLeaveDay || bobArriveDay > aliceLeaveDay) {//alice/bob到的时候 bob/alice已经走了 共同度过的日子为0
                    return 0;
                } else {
                    //alice先到
                    if (aliceArriveDay <= bobArriveDay) {
                        return aliceLeaveDay <= bobLeaveDay ? (aliceLeaveDay-bobArriveDay)+1 : (bobLeaveDay-bobArriveDay)+1;
                    //alice后到
                    } else {
                        return aliceLeaveDay <= bobLeaveDay ? (aliceLeaveDay-aliceArriveDay)+1 : (bobLeaveDay-aliceArriveDay)+1;
                    }
                }
            //alice走的月份小于bob 即alice先走
            }else if (aliceLeaveMonth<bobLeaveMonth){
                if (aliceLeaveDay==bobArriveDay){
                    return 1;
                }else {
                    int sumDays = aliceLeaveDay;
                    for (int i = aliceArriveMonth+1; i < aliceLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += aliceArriveDay>=bobArriveDay ? getMonthDays(aliceArriveMonth)-aliceArriveDay : getMonthDays(bobArriveMonth)-bobArriveDay;
                    return sumDays+1;
                }
            //alice走的月份大于bob 即bob先走
            }else {
                int sumDays = 0;
                if (bobArriveMonth==bobLeaveMonth){
                    sumDays += bobLeaveDay - bobArriveDay;
                }else {
                    sumDays = bobLeaveDay;
                    for (int i = bobArriveMonth+1; i <bobLeaveMonth ; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += aliceArriveDay>=bobArriveDay ? getMonthDays(aliceArriveMonth)-aliceArriveDay : getMonthDays(bobArriveMonth)-bobArriveDay;
                }
                return sumDays+1;
            }


        //alice月份先到
        } else if (aliceArriveMonth < bobArriveMonth) {
            if (aliceLeaveMonth < bobArriveMonth) {//alice在bob到之前就走了
                return 0;
            //alice 走 的那个月 bob 到
            } else if (aliceLeaveMonth == bobArriveMonth) {
                if(aliceLeaveDay<=bobLeaveDay){
                    return bobArriveDay < aliceLeaveDay ? (aliceLeaveDay-bobArriveDay)+1 : 0;
                }else {
                    return bobArriveDay < aliceLeaveDay ? (bobLeaveDay-bobArriveDay)+1 : 0;
                }
            //alice在bob到的月份之后的月份才走
            } else {
                //bob走的月份小于alice
                if (bobLeaveMonth < aliceLeaveMonth) {
                    int sumDays = getMonthDays(bobArriveMonth) - bobArriveDay;
                    for (int i = bobArriveMonth + 1; i < bobLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += bobLeaveDay;
                    return sumDays+1;
                //bob走的月份大于alice
                } else if (bobLeaveMonth > aliceLeaveMonth) {
                    int sumDays = getMonthDays(bobArriveMonth) - bobArriveDay;
                    for (int i = bobArriveMonth + 1; i < aliceLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += aliceLeaveDay;
                    return sumDays+1;
                //bob跟alice一个月走
                }else {
                    int sumDays = getMonthDays(bobArriveMonth) - bobArriveDay;
                    for (int i = bobArriveMonth + 1; i < aliceLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += Math.min(aliceLeaveDay,bobLeaveDay);
                    return sumDays+1;
                }
            }
        //bob月份先到
        } else {
            if (bobLeaveMonth < aliceArriveMonth) {//bob在alice到之前就走了
                return 0;
                //bob 走 的那个月 alice 到
            } else if (bobLeaveMonth == aliceArriveMonth) {
                return aliceArriveDay < bobLeaveDay ? (bobLeaveDay-aliceArriveDay)+1 : 0;
                //bob在alice到的月份之后的月份才走
            } else {
                //alice走的月份小于bob
                if (aliceLeaveMonth < bobLeaveMonth) {
                    int sumDays = getMonthDays(aliceArriveMonth) - aliceArriveDay;
                    for (int i = aliceArriveMonth + 1; i < aliceLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += aliceLeaveDay;
                    return sumDays+1;
                //alice走的月份大于bob
                } else if (aliceLeaveMonth > bobLeaveMonth) {
                    int sumDays = getMonthDays(aliceArriveMonth) - aliceArriveDay;
                    for (int i = aliceArriveMonth + 1; i < bobLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += bobLeaveDay;
                    return sumDays+1;
                //alice跟bob一个月走
                }else {
                    int sumDays = getMonthDays(aliceArriveMonth) - aliceArriveDay;
                    for (int i = aliceArriveMonth + 1; i < aliceLeaveMonth; i++) {
                        sumDays += getMonthDays(i);
                    }
                    sumDays += Math.min(aliceLeaveDay,bobLeaveDay);
                    return sumDays+1;
                }
            }
        }
    }
    //获取月份对应的天数
    public static int getMonthDays(int i){
        switch (i){
            case 1: return 31;
            case 2: return 28;
            case 3: return 31;
            case 4: return 30;
            case 5: return 31;
            case 6: return 30;
            case 7: return 31;
            case 8: return 31;
            case 9: return 30;
            case 10: return 31;
            case 11: return 30;
            case 12: return 31;
            default: return 0;
        }

    }
}




官方解较为巧妙,大家可以学习:

在这里插入图片描述
在这里插入图片描述

package keepcoding.leetcode.leetcode2409;
/*
我们可以设计一个函数 calculateDayOfYear 来计算输入中的每个日子在一年中是第几天。
计算输入中的每个日子在一年中是第几天时,可以利用前缀和数组来降低每次计算的复杂度。
知道每个日子是一年中的第几天后,可以先通过比较算出两人到达日子的最大值,离开日子的最小值,然后利用减法计算重合的日子
*/


public class Result02 {
    public static void main(String[] args) {
        int days = countDaysTogether("10-01","11-01","11-01","12-31");
        System.out.println(days);
    }
    public static int countDaysTogether(String arriveAlice, String leaveAlice, String arriveBob, String leaveBob) {
        //将每个月份的天数存入数组
        int[] datesOfMonths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        //累加数组——计算每个月在这一年已经过了多少天
        int[] prefixSum = new int[13];
        for (int i = 0; i < 12; i++) {
            //i+1 是因为要在数组1-12的位置上一一对应的存入月份累加的天数  eg.一月这一年过了31天   二月过了31+28 三月31+28+31 ...
            prefixSum[i + 1] = prefixSum[i] + datesOfMonths[i];
        }
        //计算alice到的天数是一年的第几天
        int arriveAliceDay = calculateDayOfYear(arriveAlice, prefixSum);
        //计算alice走的天数是一年的第几天
        int leaveAliceDay = calculateDayOfYear(leaveAlice, prefixSum);
        //计算bob到的天数是一年的第几天
        int arriveBobDay = calculateDayOfYear(arriveBob, prefixSum);
        //计算bob走的天数是一年的第几天
        int leaveBobDay = calculateDayOfYear(leaveBob, prefixSum);
        //用Math.min(leaveAliceDay, leaveBobDay)计算谁先走的,Math.max(arriveAliceDay, arriveBobDay)计算谁后到的
        //如果存在共处的时间,先走的-后到的即为共处的天数
        //如果先走的-后到的 < 0 证明没有相遇共处的时间——return 0;
        // +1 是因为 如果alice走的那天bob到 根据题意这也算共处了一天 eg .alice 10-01到 10-31走 bob 10-31到 11-3走 ;根据先走的-后到的计算=0,但是有共处的一天,所以+1
        return Math.max(0, Math.min(leaveAliceDay, leaveBobDay) - Math.max(arriveAliceDay, arriveBobDay) + 1);
    }
    //计算是哪一天到的
    public static int calculateDayOfYear(String day, int[] prefixSum) {
        //String类的substring()方法 ——截取字符串  https://blog.csdn.net/Crezfikbd/article/details/119708978
        int month = Integer.parseInt(day.substring(0, 2));
        int date = Integer.parseInt(day.substring(3));
        return prefixSum[month - 1] + date;//到的这个月的前一个月总共过了多少天 再加上这个月到的日期 即为这一年的第几天
    }
}



知道思路后自己又手敲了一遍:

package keepcoding.leetcode.leetcode2409;

public class DoItAgain {
    public static void main(String[] args) {
        int days = countTogetherDays("10-01","11-01","11-01","12-31");
        System.out.println(days);
    }
    //计算哪天到
    public static int countTogetherDays(String aliceArrive,String aliceLeave,String bobArrive,String bobLeave){
        int[] monthDays = {31,28,31,30,31,30,31,31,30,31,30,31};
        int[] preMonthSum = new int[13];
        for (int i = 0; i < monthDays.length; i++) {
            preMonthSum[i+1] = preMonthSum[i] + monthDays[i];
        }
        //计算alice一年中的第几天到
        int aComDay = countDay(aliceArrive,preMonthSum);
        //计算alice一年中的第几天走
        int aGoDay = countDay(aliceLeave,preMonthSum);
        //计算bob一年中的第几天到
        int bComDay = countDay(bobArrive,preMonthSum);
        //计算bob一年中的第几天走
        int bGoDay = countDay(bobLeave,preMonthSum);
        if (bComDay>aGoDay || aComDay>bGoDay){
            //没有相遇
            return 0;
        }else {
            //先走的-后到的日期
            return  Math.min(aGoDay,bGoDay) - Math.max(aComDay,bComDay) + 1;
        }

    }
    //计算各个时间点是这一年的第多少天
    public static int countDay(String s,int[] preMonthSum){
        //转化截取的字符串——得到到达的月份、日期
        int month = Integer.parseInt(s.substring(0,2));
        int day = Integer.parseInt(s.substring(3));
        //根据累加的数组结合当月到达的日期    计算到达的天数
        return preMonthSum[month-1]+day;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1120190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【每周一测】Java阶段二第四周学习

目录 1、request中的getParameter(String name)方法的功能是 2、request中的getParameter(String name)方法的功能是 3、spring创建bean对象没有以下哪个方式 4、spring依赖注入中没有以下哪个方式 5、RequestParam、RequestBody、PathVariable的应用场景及区别 6、Cooki…

第三章 网络主机扫描

本章是进入渗透测试工作流程的第一步。无论你是高级还是新手&#xff0c;本章都将帮助你成功地进行网络扫描。在开始扫描网络之前&#xff0c;我们将介绍您需要了解的基础知识。之后&#xff0c;我们将深入研究如何扫描网络目标。本章涵盖以下内容: 一、网络基础 二、识别活主…

BUUCTF 大白 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 看不到图&#xff1f; 是不是屏幕太小了 。 密文&#xff1a; 下载附件后解压&#xff0c;发现一张名为dabai.png的图片。 &#xff08;似乎因为文件被修改过&#xff0c;原图片无法放在这里&#xff0c;这张图片是…

Linux:firewalld防火墙-基础使用(2)

上一章 Linux&#xff1a;firewalld防火墙-介绍&#xff08;1&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/133960695?spm1001.2014.3001.5501 我使用的系统为centos7 firewalld启动停止等操作 systemctl start firewalld 开启防火墙 systemct…

怎么去别人的github工程下载

1、网络 确保网络能够顺利访问github&#xff0c;有的地方的公共网络不能访问github&#xff0c;我之前开过科学上网的会员&#xff0c;发现没必要特意开去访问它。可以直接开手机热点&#xff0c;一般是可以顺利访问的。 2、下载 以我的github开源笔记qq-hh/C_review (gith…

砖家预测:腾讯云双11服务器优惠价格表(新鲜出炉)

2023腾讯云双十一服务器优惠价格表多少钱一年&#xff1f;轻量服务器2核2G3M、2核2G4M、2核4G5M、4核8G12M、8核16G18M、16核32G28M和云服务器CVM标准型S5实例优惠价格&#xff0c;腾讯云百科今年双11服务器价格会在当前的价格基础上享受个9折优惠&#xff0c;可领券 https://c…

网站技术查看

当打开一个网页感觉很好奇&#xff0c;他使用了什么框架和什么技术&#xff1f; 常用的网页技术分析网站。 1. w3techs Check web technologies used by a website - Site InfoW3Techs identifies which web technologies such as CMS, programming language, web server an…

Python中的内存管理:深入分析垃圾回收机制

python中有一个名为refchian的环状双向链表&#xff0c;python运行时创建的所有对象都会添加到refchain中。在refchain中的对象PyObject里都有一个ob_refcnt用来保存当前对象的引用计数器&#xff0c;就是该对象被引用的次数&#xff0c;当对象有新引用时ob_refcnt就会增加&…

最简单修改nacos的修改权重修改上线下线报错

前言 我在docker中部署了一个单体的nacos服务,过了一段时间,由于我导入了另外一个nacos的服务配置导致服务注册没问题,但是服务的修改权重和修改服务的上线下线会报错.于是就有了这篇文章,这篇文章主要是解决上面说的问题 正文 1.报错信息展示(这里我已经修复过了已经展示不了了…

【iOS】简单的网络请求

应iOS小组要求&#xff0c;仿写知乎日报需要实现网络请求并解析JSON格式数据&#xff0c;这篇文章仅对基本的网络请求和iOS中的JSON解析作以记录&#xff0c;还涉及到RunLoop的一点小插曲&#xff0c;具体请求过程和原理以后会详细学习&#xff01;&#x1f64f; 基本网络流程简…

42915-2023 铜精矿及主要含铜物料鉴别规范

1 范围 本文件规定了铜精矿及主要含铜物料的鉴别特征、鉴别流程、鉴别实施及鉴别报告编写。 本文件适用于进口铜精矿与主要含铜物料的鉴别&#xff0c;主要含铜物料包括冰铜、铜火法冶炼渣、铜火法 冶炼烟尘、铜阳极泥、铜渣精矿等铜火法冶炼工艺产生的物料。 2 规范性引用…

前端Vue框架系列—— 学习笔记总结Day02

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…

VMwarePlayer安装Ubuntu,切换中文并安装中文输入法

1.下载和安装 虚拟机使用的免费版官网链接&#xff1a;VMwarePlayer Ubuntu镜像下载官网链接&#xff1a;Ubuntu桌面版 自己学习使用&#xff0c;不需要考虑迁移之类的。选择单个磁盘IO性能会更高 安装过程中如果出现如下报错&#xff0c;则用系统管理员身份运行 右击VMwa…

造车先做三蹦子220101--机器学习字符(字母、和数字识别)的“小白鼠”与“果蝇”

“0”数字字符零 的图片(16*16点阵)&#xff1a; import torch import torch.nn as nn import torch.optim as optim from PIL import Image, ImageDraw, ImageFont from torchvision import transforms import matplotlib.pyplot as pltTimes20001000# 参数设置 font_path &q…

嵌入式实时操作系统的设计与开发(内存资源池存储管理)

内存资源池存储管理 内存资源池存储管理属于固定大小内存管理系统&#xff0c;内存池中内存块的分配和回收是基于第一级内存管理系统的&#xff0c;因为内存池中内存块是由第一级内存管理的算法所确定的。 内存池存储管理系统主要用于操作系统的一些常用结构的内存管理。例如…

位操作符^以及正负数在计算机中的存储

(数据是怎么在计算机中存储的)​ 正数和负数在内存中都是以补码的形式存储的&#xff0c;但不同的是正数的原码&#xff0c;补码&#xff0c;反码都是相同的&#xff0c;而负数的原码&#xff0c;补码和反码是不同的。 负数的原码&#xff0c;补码&#xff0c;反码之间存在什么…

神仙级价格:腾讯云双十一服务器优惠价格表来了

2023腾讯云双十一服务器优惠价格表多少钱一年&#xff1f;轻量服务器2核2G3M、2核2G4M、2核4G5M、4核8G12M、8核16G18M、16核32G28M和云服务器CVM标准型S5实例优惠价格&#xff0c;腾讯云百科今年双11服务器价格会在当前的价格基础上享受个9折优惠&#xff0c;可领券 https://c…

【Java】一只小菜坤的编程题之旅【4】

文章目录 1丶合并两个有序链表2丶栈的压入、弹出序列3丶设计循环队列4丶最小栈 1丶合并两个有序链表 小菜坤的答案&#xff1a; class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode newHeadnew ListNode(0);ListNode tmpnewHead;while…

Git的介绍和命令汇总

目录 一、git介绍 1、git的工作区域 2、git中文件的四种状态 二、常用命令 1、基础命令 2、提交类命令 3、删除类命令 4、分支类相关命令 5、 查看类相关命令 6、撤销类命令 一、git介绍 1、git的工作区域 在Git中&#xff0c;有四个工作区域&#xff1a;工作区域&am…

k8s认证

1. 证书介绍 服务端保留公钥和私钥&#xff0c;客户端使用root CA认证服务端的公钥 一共有多少证书&#xff1a; *Etcd&#xff1a; Etcd对外提供服务&#xff0c;要有一套etcd server证书Etcd各节点之间进行通信&#xff0c;要有一套etcd peer证书Kube-APIserver访问Etcd&a…