ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【力扣时间】【1154】【简单】一年中的第几天

2021-12-21 13:00:15  阅读:198  来源: 互联网

标签:seg 闰年 第几天 get int 1154 31 力扣 year


一年中的第几天

今天的题,有些一言难尽啊……

1、看看题

我是题
题目写得挺详细的,给的case也挺好,照顾到了一些特殊情况。

2、审题

看完题目,各位应该都会会心一笑。
啊?就这就这?

到底是简单题嘛

题目没有藏什么陷阱。如果有,也只能说是和我们生活息息相关的一些常识问题——闰年。
作为格里高利历中特殊的一个年份,我们都知道闰年时,2月会出现第29天。而这也是题目唯一的烟雾弹了。

看看重点:

  1. 输入是一串字符串,题目保证了其正确性和格式(YYYY-MM-DD)。
  2. 输出的是该日期在当年中的天数,第一天则返回1。
  3. 注意闰年的2月份会多一天。

这题的重点几乎都在闰年的判断上了,我本来是这么认为的……

3、思路

很明显,今天的题目有两个点需要解决:

  1. 解析输入的字符串。
  2. 闰年的判断。

相信各位使用java语言开发的社畜,多少都有在业务中接触过日期字符串转换的需求。
我比较常用的是apache common包提供的StringUtils工具类,简单又刺激。
但是leetcode明显不会让我们用这些第三方的包……

总之,关于问题1,我们还有很多土办法。
由于题目保证了字符串的正确性,我们直接通过“-”拆分字符串,并将各个部分转型为int即可。
问题2的话,就属于常识问题了(不懂可以百度 ),4的整数倍但不是100的整数倍,或为400的整数倍的年份,即为闰年。

开工!

4、撸代码

class Solution {

    public int dayOfYear(String date) {
        String[] seg = date.split("-");
        List<Integer> info = Arrays.stream(seg).map(Integer::parseInt).collect(Collectors.toList());
        Calendar calendar = new GregorianCalendar(info.get(0), info.get(1) - 1, info.get(2));
        return calendar.get(Calendar.DAY_OF_YEAR);
    }
}

这是我满心欢喜地写完的第一版,使用Calendar 和其子类,能够帮我我们解决日期相关的几乎所有问题。
但是……丫的leetcode居然不支持使用Calendar !
在这里插入图片描述
你们用的到底是什么版本的jdk!高等语言的便利的工具类居然都不让用!不过用了还写什么算法啊.

没办法,改改吧……

class Solution {

    public int dayOfYear(String date) {
        List<Integer> seg = Arrays.stream(date.split("-")).map(Integer::parseInt).collect(Collectors.toList());
        //获取年月日
        int year = seg.get(0);
        int month = seg.get(1);
        int day = seg.get(2);

        //初始化每月的第一天所在的当年的第几天
        int[] dayOfMonth = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int[] daysOfMonth = new int[12];
        daysOfMonth[0] = 0;
        for (int i = 1; i < 12; i++) {
            daysOfMonth[i] = daysOfMonth[i - 1] + dayOfMonth[i - 1];
        }

        //注意闰年时2月要+1天
        return day + daysOfMonth[month - 1] + (month > 2 && isLeapYear(year) ? 1 : 0);
    }

    /**
     * 判断闰年的条件:
     * 为400的整数倍,或为4但不为100的整数倍
     *
     * @param year 年份
     * @return 是否为闰年
     */
    private boolean isLeapYear(int year) {
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }
}

于是,就出现了第二版土法子……

5、解读

isLeapYear()方法用来判断年份是否为闰年。
判断逻辑也正如上面提到的:400的整数倍 或 4的整数倍但不为100的整数倍。

private boolean isLeapYear(int year) {
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }

主函数中,我通过spilt拆分字符串,并将各个部分转型为int,这种写法有写耗时,但懒得改了。

List<Integer> seg = Arrays.stream(date.split("-")).map(Integer::parseInt).collect(Collectors.toList());
        //获取年月日
        int year = seg.get(0);
        int month = seg.get(1);
        int day = seg.get(2);

之后的步骤正如注释所说,是为了计算每月的第一天在当年是第几天。这里运用到了一点前缀和的思想。这样,我们只用知道日期所在的月份,就能快速得到该月的第一天在该年是第几天,加上日期就能得到最终答案。

		//初始化每月的第一天所在的当年的第几天
		int[] dayOfMonth = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int[] daysOfMonth = new int[12];
        daysOfMonth[0] = 0;
        for (int i = 1; i < 12; i++) {
            daysOfMonth[i] = daysOfMonth[i - 1] + dayOfMonth[i - 1];
        }

当然,也不要忘了闰年这个特殊情况。

//注意闰年时2月要+1天
return day + daysOfMonth[month - 1] + (month > 2 && isLeapYear(year) ? 1 : 0);

6、提交

在这里插入图片描述
时间排名惊人地低,但懒得优化了。
毕竟思路如此,我也能接受了。

7、咀嚼

时间复杂度和空间复杂度都是O(1),这应该没什么好说的。

8、偷知识可不算偷

鲸了!不能用Calendar但居然能用LocalDate
这样真的能做到一句话写完了:

public int dayOfYear(String date) {
        return LocalDate.parse(date).getDayOfYear();
    }

以上,都是在题解里看到的其他大牛的解放。
除了依赖官方api的,其他的做法都大同小异

但还是分享一下其他大牛的以供参考

9、总结

总的收获不多,但善于使用各种语言丰富的api,会让你的算法简单很多。
除此之外,就算不用亲自实现,也请牢记各种思路,以备不时之需。
只是这样还算是写算法吗?

简单题,简单地做。
祝大家冬至愉快,记得吃饺子哦。

在这里插入图片描述

标签:seg,闰年,第几天,get,int,1154,31,力扣,year
来源: https://blog.csdn.net/qq_19917031/article/details/122057075

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有