1154. 一年中的第几天
https://leetcode-cn.com/classic/problems/ordinal-number-of-date/description/
给你一个按 YYYY-MM-DD 格式表示日期的字符串 date,请你计算并返回该日期是当年的第几天。
通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类推。每个月的天数与现行公元纪年法(格里高利历)一致。
示例 1:
输入:date = "2019-01-09"
输出:9示例 2:
输入:date = "2019-02-10"
输出:41示例 3:
输入:date = "2003-03-01"
输出:60示例 4:
输入:date = "2004-03-01"
输出:61提示:
date.length == 10
date[4] == date[7] == '-',其他的 date[i] 都是数字。
date 表示的范围从 1900 年 1 月 1 日至 2019 年 12 月 31 日。
分别求出年月日,再做闰年的判断,时间一加就好了
class Solution {
public:
int dayOfYear(string date) {
int ms[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int ans=0;
int y = stoi(date.substr(0,4));
int m = stoi(date.substr(5,2));
int d = stoi(date.substr(8));
if((y%4==0&&y%100!=0)||y%400==0) ms[2]++;
for(int i=1;i<m;i++) ans+=ms[i];
ans+=d;
return ans;
}
};
1155. 掷骰子的N种方法
https://leetcode-cn.com/classic/problems/number-of-dice-rolls-with-target-sum/
这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, ..., f。
我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和。
如果需要掷出的总点数为 target,请你计算出有多少种不同的组合情况(所有的组合情况总共有 f^d 种),模 10^9 + 7 后返回。示例 1:
输入:d = 1, f = 6, target = 3
输出:1
示例 2:
输入:d = 2, f = 6, target = 7
输出:6
示例 3:
输入:d = 2, f = 5, target = 10
输出:1
示例 4:
输入:d = 1, f = 2, target = 3
输出:0
示例 5:
输入:d = 30, f = 30, target = 500
输出:222616187提示:
1 <= d, f <= 30
1 <= target <= 1000
dp即可,dp[m][n]表示用了m个筛子后的总点数n,
所以dp[i][j]可以由dp[i-1][j-k]得到,其中,k为筛子可掷的点数
class Solution {
public:
int numRollsToTarget(int d, int f, int target)
{
int mod = 1e9 + 7;
int dp[d+2][target+2];
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=d;i++)
{
for(int j=1;j<=target;j++)
{
for(int k=1;k<=f && k<=j;k++) dp[i][j] = (dp[i][j]+dp[i-1][j-k])%mod;
}
}
return dp[d][target];
}
};
1156. 单字符重复子串的最大长度
https://leetcode-cn.com/classic/problems/swap-for-maximum-repeated-substring/description/
如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。
给你一个字符串 text,你只能交换其中两个字符一次或者什么都不做,然后得到一些单字符重复的子串。返回其中最长的子串的长度。示例 1:
输入:text = "ababa"
输出:3
示例 2:
输入:text = "aaabaaa"
输出:6
示例 3:
输入:text = "aaabbaaa"
输出:4
示例 4:
输入:text = "aaaaa"
输出:5
示例 5:
输入:text = "abcdef"
输出:1提示:
1 <= text.length <= 20000
text 仅由小写英文字母组成。
这道题我是先遍历一遍求出每个字母的数量nums,用count记录当前遍历字母的连续数量,k表示交换情况,maxx为结果。
因为题目要求只能交换一次,那么肯定要换过来相同的字母才有更大的连续数量,我们可以考虑这一次交换有什么情况,
- 交换后右边是不同的字母,maxx只能在交换前的数量上加1
- 交换后右边是相同的字母,可以继续往右边计算
如果直接在字符串里交换,不便于后续遍历,我们可以考虑用k来记录是否交换过字母,然后跳过这一位(本来这里要判断count<nums才进行交换,但由于我的写法,在最后一位的判断中其实把这里包含了,此处可默认为都能跳一次)从后一位接着计算连续count,然后注意最后边界值的处理
class Solution {
public:
int maxRepOpt1(string text)
{
int nums[26],maxx=0,count=0,k=0;
int N=text.length();
memset(nums,0,sizeof(nums));
for(int i=0;i<N;i++) nums[text[i]-'a']++;
for(int i=0;i<N;i++)
{
int x = text[i];
count = 1;
k=0;
// printf("\ni=%d ,x=%c\n",i,x);
for(int j=i+1;j<=N;j++)
{
if(j!=N && x==text[j]) count++;
else if(k || j>=N-1)
{
if(count<nums[x-'a']) count++;
maxx = max(count,maxx);
break;
}
else
{
k=1;
}
// printf("j=%d ,text[j]=%c,count=%d,k=%d\n",j,text[j],count,k);
}
}
return maxx;
}
};