leetcode
leetcode 1101 ~ 1150
日期之间隔几天

日期之间隔几天

难度:

标签:

题目描述

代码结果

运行时间: 23 ms, 内存: 16.0 MB


/*
  思路:
  - 通过使用 Java Stream 的方式来计算两个日期之间的天数。
  - Stream 的使用可以使代码更加简洁,但由于时间计算的特殊性,主要还是依赖于 LocalDate 的处理。
*/
import java.time.LocalDate;
import java.util.stream.Stream;

public class DateDifferenceStream {
    public static int daysBetween(String date1, String date2) {
        // 转换日期字符串为 LocalDate 对象
        LocalDate d1 = LocalDate.parse(date1);
        LocalDate d2 = LocalDate.parse(date2);
        // 使用 Stream 的方式计算日期差
        return Stream.of(d1, d2)
                     .mapToInt(date -> (int) ChronoUnit.DAYS.between(d1, d2))
                     .reduce((a, b) -> b) // 只需计算一次
                     .orElse(0);
    }
}

解释

方法:

该题解使用了一种数学计算的方法来计算两个日期之间的天数差。首先,为了方便计算,题解选择了一个基准日期(1971年1月1日)并计算从这个日期到给定日期的天数。这是通过以下步骤实现的:1. 计算从基准年到给定年份之前的完整年份中的天数,假设每年有365天。2. 使用一个预先计算好的数组 month_sum,该数组存储了在非闰年中,从年初到每个月第一天前的累积天数,使用这个数组可以快速得到从年初到指定月份的天数。3. 加上月内的天数。4. 考虑闰年对结果的影响,每四年有一个闰年(2月29日),因此需要添加相应的天数。然而,由于范围到2100年,需要特别处理2100年,因为它虽然能被4整除,但不是闰年。5. 最后,计算两个日期的天数差,将两个日期分别转换为从基准日期到它们的天数,然后取绝对值。

时间复杂度:

O(1)

空间复杂度:

O(1)

代码细节讲解

🦆
为什么在计算年份天数差时使用`(year-1971)*365`而不直接计算每个年份的实际天数,包括闰年的处理?
使用`(year-1971)*365`来计算基础天数是为了简化计算过程。首先,这一步计算假定了除了闰年外的所有年份都是365天,这使得年份的天数计算变得非常直接和快速。接着,通过另外计算闰年带来的额外天数,并进行相应的调整,可以有效地处理闰年。这种分步计算的方法,既简化了计算流程,也保证了计算的准确性。
🦆
数组`month_sum`是如何构建的,它是否正确处理了所有月份的天数,尤其是闰年的2月份?
数组`month_sum`是根据非闰年中每个月之前的天数累加构建的。它的设计是为了快速从年初到给定月份的天数进行查找,而不需要对每个月份逐个累加天数。对于闰年的特殊处理(2月29天),在计算总天数时通过检查年份和月份来进行调整。如果是闰年且日期在2月29日之后,需要在结果中额外加一天。这样,`month_sum`虽然基于非闰年构建,但通过条件判断正确处理了闰年2月的情况。
🦆
在处理闰年时,为什么使用`(year-1968) // 4`来计算从1971年以来的闰年数量?1968年与1971年之间的关系是什么?
使用`(year-1968) // 4`是为了计算从1968年开始到指定年份之前的闰年数量。这是因为1971年是计算的基准年,而闰年的周期是每4年一次。通过从1968年开始计算,可以确保这一周期的正确对齐(1968年是闰年)。这样,确保了从1971年到给定年份的计算中闰年被正确计算。
🦆
题解中提到对2100年进行特殊处理,因为它虽被4整除但不是闰年。请问如何正确实现这种例外年份的处理?
对2100年的特殊处理是在计算过程中进行的。虽然2100年能被4整除,按常规判断应是闰年,但按照格里高利历规则,因为它不能被100整除却不能被400整除,所以它不是闰年。在代码中,特别检查了这一年份,如果计算的年份是2100且计算的日期位于3月1日或之后,由于2100年2月没有29日,所以需要从总天数中减去1天,以反映这一非闰年状态。

相关问题