LeetCode-in-Java

920. Number of Music Playlists

Hard

Your music player contains n different songs. You want to listen to goal songs (not necessarily different) during your trip. To avoid boredom, you will create a playlist so that:

Given n, goal, and k, return the number of possible playlists that you can create. Since the answer can be very large, return it modulo 109 + 7.

Example 1:

Input: n = 3, goal = 3, k = 1

Output: 6

Explanation: There are 6 possible playlists: [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], and [3, 2, 1].

Example 2:

Input: n = 2, goal = 3, k = 0

Output: 6

Explanation: There are 6 possible playlists: [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2, 1], [2, 1, 2], and [1, 2, 2].

Example 3:

Input: n = 2, goal = 3, k = 1

Output: 2

Explanation: There are 2 possible playlists: [1, 2, 1] and [2, 1, 2].

Constraints:

Solution

import java.util.Arrays;

public class Solution {
    public int numMusicPlaylists(int n, int l, int k) {
        long[][] dp = new long[l][n + 1];
        for (int i = 0; i < l; i++) {
            Arrays.fill(dp[i], -1);
        }
        return (int) helper(0, l, 0, n, k, dp);
    }

    private long helper(int songNumber, int l, int usedSong, int n, int k, long[][] dp) {
        if (songNumber == l) {
            return usedSong == n ? 1 : 0;
        }
        if (dp[songNumber][usedSong] != -1) {
            return dp[songNumber][usedSong];
        }
        long ans;
        if (songNumber < k) {
            ans = (n - usedSong) * helper(songNumber + 1, l, usedSong + 1, n, k, dp);
        } else if (usedSong == n) {
            ans = (usedSong - k) * helper(songNumber + 1, l, usedSong, n, k, dp);
        } else {
            ans =
                    (n - usedSong) * helper(songNumber + 1, l, usedSong + 1, n, k, dp)
                            + (usedSong - k) * helper(songNumber + 1, l, usedSong, n, k, dp);
        }
        int mod = (int) 1e9 + 7;
        dp[songNumber][usedSong] = ans % mod;
        return ans % mod;
    }
}