LeetCode 149 周赛

1. 题目列表

  • 一年中的第几天(简单)
  • 投掷骰子的N种方法(背包问题求方案数)
  • 单字符重复子串的最大长度
  • 子数组种占绝大多数的元素(求第k小问题)

2. 一年中的第几天

给你一个按 YYYY-MM-DD 格式表示日期的字符串 date,请你计算并返回该日期是当年的第几天。

通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类推。每个月的天数与现行公元纪年法(格里高利历)一致。

代码:

class Solution {
public:
    int daysRun[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int daysCom[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    bool isRun(int year){
        // 闰年:能被4整除,且不被100整除,或者能被400整除
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
            return true;
        else return false;
    }
    
    int dayOfYear(string date) {
        // 两种年:闰年和平年
        int year = 0, month = 0, day = 0;
        for (int i = 0; i <= 3; i++)
            year = year * 10 + (date[i] - '0'); 
        month = (date[5] - '0') * 10 + (date[6] - '0');
        day = (date[8] - '0') * 10 + (date[9] - '0');
        int res = 0;
        for (int i = 0; i < month - 1; i++)
            if (isRun(year))    res += daysRun[i];
            else res += daysCom[i];
        res += day;
        return res;
    }
};

3. 掷骰子的N种方法

题目描述:
这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, ..., f。

我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和。

如果需要掷出的总点数为 target,请你计算出有多少种不同的组合情况(所有的组合情况总共有 f^d 种),模 10^9 + 7 后返回。

解决思路:
定义dp[i][j]表示前i个骰子组成的和恰好为j的方案数,则有状态转移方程
dp[i][j]=\sum_{k=1}^{f} dp[i-1][j-k]边界条件:dp[0][0] = 1,其他为0

代码:

const int MOD = 1e9+7;
class Solution {
public:
    int dp[35][1005];
    int numRollsToTarget(int d, int f, int target) {
        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++) {
                    if(j - k >= 0) {
                        dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;
                    }
                }
            }
        }
    return dp[d][target];
    }
};

推荐阅读更多精彩内容