Easy
题目描述
给你一个字符串 date,它是一个按照格式 YYYY-MM-DD 表示的格里高利历日期,返回该日期是一年中的第几天。
示例 1:
输入:date = "2019-01-09"
输出:9
解释:给定日期是2019年的第9天。
示例 2:
输入:date = "2019-02-10"
输出:41
约束条件:
date.length == 10date[4] == date[7] == '-',其他的date[i]都是数字date表示的范围从 1900 年 1 月 1 日到 2019 年 12 月 31 日
提示:
- 可以使用一个整数数组来存储每个月的天数。如果是闰年,二月会多一天。然后,我们可以手动计算序数:当前月的天数 +(该月之前所有月份的天数)。
解题思路
这道题要求计算给定日期是一年中的第几天。我们可以采用以下思路:
方法一:累加计算
- 解析输入字符串,提取年、月、日信息
- 预先定义每个月的天数数组
- 判断是否为闰年,如果是闰年且已经过了2月,需要额外加1天
- 累加目标月份之前所有月份的天数,再加上当前月的天数
闰年判断规则:
- 能被400整除,或者能被4整除但不能被100整除
方法二:使用内置日期库 某些语言提供了日期处理库,可以直接计算,但为了算法练习,建议使用方法一。
这道题的关键在于正确处理闰年的情况。实现时需要注意字符串解析和边界条件的处理。
时间复杂度为O(1),因为最多只需要遍历12个月;空间复杂度也是O(1),只需要常数级别的额外空间。
代码实现
class Solution {
public:
int dayOfYear(string date) {
int year = stoi(date.substr(0, 4));
int month = stoi(date.substr(5, 2));
int day = stoi(date.substr(8, 2));
vector<int> days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 判断是否为闰年
bool isLeapYear = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if (isLeapYear) {
days[1] = 29;
}
int result = day;
for (int i = 0; i < month - 1; i++) {
result += days[i];
}
return result;
}
};
class Solution:
def dayOfYear(self, date: str) -> int:
year, month, day = map(int, date.split('-'))
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# 判断是否为闰年
is_leap_year = (year % 400 == 0) or (year % 4 == 0 and year % 100 != 0)
if is_leap_year:
days[1] = 29
return day + sum(days[:month-1])
public class Solution {
public int DayOfYear(string date) {
string[] parts = date.Split('-');
int year = int.Parse(parts[0]);
int month = int.Parse(parts[1]);
int day = int.Parse(parts[2]);
int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
// 判断是否为闰年
bool isLeapYear = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
if (isLeapYear) {
days[1] = 29;
}
int result = day;
for (int i = 0; i < month - 1; i++) {
result += days[i];
}
return result;
}
}
/**
* @param {string} date
* @return {number}
*/
var dayOfYear = function(date) {
const [year, month, day] = date.split('-').map(Number);
const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
daysInMonth[1] = 29;
}
let dayOfYear = day;
for (let i = 0; i < month - 1; i++) {
dayOfYear += daysInMonth[i];
}
return dayOfYear;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(1) | 最多遍历12个月,常数时间 |
| 空间复杂度 | O(1) | 只使用了固定大小的数组和几个变量 |