前言
刷5月17日的老题。今天刷的是557.反转字符串中的单词 III、54.螺旋矩阵、920.播放列表的数量。
557.反转字符串中的单词 III(容易):
题目描述:
给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
示例:
输入: “Let’s take LeetCode contest”
输出: “s’teL ekat edoCteeL tsetnoc”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii
题解:
直接的做法是,向后搜索,用临时串对单词进行反序,遇到空格就重置临时串并增加空格,直到遇到新单词,重复上述操作。时间复杂度O(n),不考虑字符串拼接花的时间的话。
也可以用内置方法,不过感觉太粗犷了…
Code
var reverseWords = function(s) {
var l = ''
var l1 = ''
for (var i = 0; i < s.length; i++){
if(s[i] != ' '){
l = s[i] + l
}else {
l1 = l1 + l + ' '
l = ''
}
}
return l1+l
//内置方法:
//return s.split("").reverse().join("").split(" ").reverse().join(" ")
};
54.螺旋矩阵(中等):
题目描述:
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/spiral-matrix
题解:
这道题好像做过了,我的逐层打印思路是下面这种:
注意终止条件是res数组的长度等于矩阵的行×列,并处理好边界的缩小就可以了。
Code
//这道题莫名眼熟,好像就是剑指offer里面的顺时针打印矩阵......
//84%,100%
var spiralOrder = function(matrix) {
if(matrix.length==0) return [];
let [row,col]=[matrix.length,matrix[0].length];
let [l,r,t,b,res]=[0,matrix[0].length-1,0,matrix.length-1,[]];
while(res.length<row*col){
for(let i=l;i<=r&&res.length<row*col;i++){
res.push(matrix[t][i]);
}
t++;
for(let i=t;i<=b&&res.length<row*col;i++){
res.push(matrix[i][r]);
}
r--;
for(let i=r;i>=l+1&&res.length<row*col;i--){
res.push(matrix[b][i]);
}
for(let i=b;i>=t&&res.length<row*col;i--){
res.push(matrix[i][l]);
}
b--;
l++;
}
return res;
};
920.播放列表的数量(困难):
题目描述:
你的音乐播放器里有 N 首不同的歌,在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复)。请你为她按如下规则创建一个播放列表:
①每首歌至少播放一次。
②一首歌只有在其他 K 首歌播放完之后才能再次播放。
返回可以满足要求的播放列表的数量。由于答案可能非常大,请返回它模 10^9 + 7 的结果。
(0 <= K < N <= L <= 100)
示例 1:
输入:N = 3, L = 3, K = 1
输出:6
解释:有 6 种可能的播放列表。[1, 2, 3],[1, 3, 2],[2, 1, 3],[2, 3, 1],[3, 1, 2],[3, 2, 1].
示例 2:
输入:N = 2, L = 3, K = 0
输出:6
解释:有 6 种可能的播放列表。[1, 1, 2],[1, 2, 1],[2, 1, 1],[2, 2, 1],[2, 1, 2],[1, 2, 2]
示例 3:
输入:N = 2, L = 3, K = 1
输出:2
解释:有 2 种可能的播放列表。[1, 2, 1],[2, 1, 2]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-music-playlists
题解:
采用动态规划的做法,难点在于状态的表示:
用dp[n][l]来表示l长度的播放列表,包含了n首歌的状态。
因为最后一首歌,我们可以播放没有播放过的歌也可以是播放过的,所以:
1、如果未播放过的,那么就是 dp[n-1][l-1] * (N-n+1) 种选择方法,因为对于dp[n][l],选择哪一首未播放歌曲放在后面,可以有(N-n+1)种情况。
2、如果不是,那么就是选择之前的一首歌,dp[n-1][l] * max(n-K, 0)(n 首歌,最近的 K 首(不重复的)不可以播放)。
因此,时间复杂度:O(NL),空间复杂度:O(NL)
Code
var numMusicPlaylists = function(N, L, K) {
// F(N,L)=F(N-1,L-1)*(N-n+1) + F(N,L-1)*(N-K)
let MOD=1000000007;
let dp=Array.from({length:N+1},_=>new Array(L+1).fill(0));
dp[0][0]=1;
for(let n=1;n<=N;n++){
for(let l=1;l<=L;l++){
dp[n][l]=((dp[n-1][l-1]*(N-n+1))%MOD+(dp[n][l-1]*Math.max(n-K,0)%MOD))%MOD;
}
}
return dp[N][L];
};