1154. 一年中的第几天
给你一个按 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
注意:
能被4整除但不能被100整除的年份为普通闰年。
能被400整除的为世纪闰年。
即闰年是能被4整除但是不能被100整除,或者能被400整除。
代码:
public int dayOfYear(String date) {
String[] str = date.split("-");
int[] data = new int[str.length];
for (int i = 0; i < str.length; i++) {
data[i] = Integer.valueOf(str[i]);
}
int sum=0;
int Mon=data[1];
int Year=data[0];
int Day=data[2];
switch(Mon){
case 12:sum += 30;
case 11:sum += 31;
case 10:sum += 30;
case 9 :sum += 31;
case 8 :sum += 31;
case 7 :sum += 30;
case 6 :sum += 31;
case 5 :sum += 30;
case 4 :sum += 31;
case 3 :
if((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0)){
//System.out.println("这一年是闰年!");
sum += 29;
}
else{
//System.out.println("这一年是平年!");
sum += 28;
}
case 2 :sum += 31;
case 1 :sum += Day;
}
System.out.println(sum);
return sum;
}
1155. 掷骰子的N种方法
这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, …, f。
我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和。
如果需要掷出的总点数为 target,请你计算出有多少种不同的组合情况(所有的组合情况总共有 f^d 种),模 10^9 + 7 (10000000007)后返回。
示例 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[i][j]表示投第i个骰子表示值为j的次数
假如第i+1个骰子扔值为d,那么转移方程:dp[i+1][j]=dp[i][j-d] (j-d>=0)
dp[0][0]=1表示刚开始还没有扔,和为0,这种情况只有1种。
代码:
//int MOD=10000000007;
int mod = (int)1e9+7;
int numRollsToTarget(int d, int f, int target) {
// dp表示投第i个骰子表示值为j的次数
int [][]dp=new int [35][1000];
dp[0][0]=1;
for(int i=1;i<=d;i++){
for(int now=1;now<=f;now++){
for(int pre=0;pre+now<=target;pre++){
dp[i][pre+now]=(dp[i][pre+now]+dp[i-1][pre]);
if(dp[i][pre+now]>=mod){
dp[i][pre+now]%=mod;
}
}
}
}
return dp[d][target];
}
1156. 单字符重复子串的最大长度
如果字符串中的所有字符都相同,那么这个字符串是单字符重复的字符串。
给你一个字符串 text,你只能交换其中两个字符一次或者什么都不做,然后得到一些单字符重复的子串。返回其中最长的子串的长度。
示例 1:
输入:text = "ababa"
输出:3
示例 2:
输入:text = "aaabaaa"
输出:6
示例 3:
输入:text = "aaabbaaa"
输出:4
示例 4:
输入:text = "aaaaa"
输出:5
示例 5:
输入:text = "abcdef"
输出:1
思路:使用区间法(双指针),区间中可以容忍一个字符不是目标字符
代码:
public int maxRepOpt1(String text) {
// 首先统计每个字符的数量,记录在数组中
int []cnt=new int[30];
for(int i=0;i<text.length();i++){
cnt[text.charAt(i)-'a']++;
}
int ans=0;
for(char c='a';c<='z';c++){
// 使用双指针 now:区间中目标字母个数,other:区间中非目标字母个数
int i=c-'a',l=0,now=0,other=0;
for(int r=0;r<text.length();r++){
// 区间重置,初始化
if(l==r){
now=other=0;
}
// r右指针当前就是目标字符,now++,否则分两种情况
if(text.charAt(r)==c){
++now;
}else{
// 1.区间内暂时全是目标字符,那么可以将当前非目标字符加入
// 2.区间内已经有一个非目标字符,那么循环从左边开始遍历,直到将那个非目标字符删除之后,再将当前非目标字符加入
while(other>=1&&l<r){
if(text.charAt(l)==c){
--now;
}else{
--other;
}
l++;
}
// 加入这个新的非目标字符
++other;
}
// 1.如果区间内包含了所有的字符,所以不能再交换,那么当前结果就是为cnt[i]
// 2.区间还不是包含所有字符,更新长度
ans=Math.max(ans,Math.min(cnt[i],r-l+1));
}
}
return ans;
}