Leetcode Contest 30
今晚参加了一个朋友的婚前庆祝party。看着朋友幸福也是一种幸福的享受。希望我的幸福来得更早一些 😆
今晚的比赛也一次没WA地过了。前面三题是用 C++ 写的,最后一题实在觉得 C++ 麻烦,还是换了用python写。
第一题Reshape the Matrix
class Solution {
public:
vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
int n = nums.size();
if (n==0) return nums;
int m = nums[0].size();
if (m==0) return nums;
if (n*m != r*c) return nums;
vector<vector<int>> ans(r, vector<int>(c, 0));
int a = 0, b = 0;
for (auto row: nums)
for (auto n: row) {
ans[a][b] = n;
b ++;
if (b == c) {
b = 0;
a ++;
}
}
return ans;
}
};
第二题Subarray Sum Equals K
假设nums的前缀和为s,也就令s[-1]=0,并且对i>=0,
那么我们要找的下面这个集合元素的个数。
我们现在可以在O(n2)的时间内暴力枚举,其中n为nums的长度,最大为20000。C++的话应该会过的。
如果我们换个角度看的话,其实可以在O(n)时间内求解。对于s[j],我们关心的是s[j]-k在s[-1], s[0], ..., s[j]中出现的次数,所以我们可以用一个哈希表统计它们出现的次数。这样对于固定的j,我们就可以在O(1)的时间内求出满足条件的(i, j)的个数。实现如下。
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> cnt;
int s = 0, ans = 0;
cnt[0] = 1;
for (int n: nums) {
s += n;
ans += cnt[s-k];
cnt[s] ++;
}
return ans;
}
};
第三题Permutation in String
关键的想法是两个字符串是互为置换当且仅当它们有相同的字符集。所以我们只要看s2中有没有一个与s1长度一样的子字符串,使得它与s1有同样的字符集。
class Solution {
public:
bool checkInclusion(string s1, string s2) {
vector<char> v1(26, 0), v2(26, 0);
int n = s1.length(), m = s2.length();
if (n>m) return false;
for (auto c: s1) v1[c-'a'] ++;
for (int i=0; i<n; i++)
v2[s2[i]-'a'] ++;
if (v1==v2) return true;
for (int i=n; i<m; i++)
{
v2[s2[i]-'a'] ++;
v2[s2[i-n]-'a'] --;
if (v1==v2) return true;
}
return false;
}
};
第四题Maximum Vacation Days
这是图上的动态规划。假设dp(i, j)表示第j步到达顶点i的最优值,需要注意的是我使用的j是从0到K-1的。
转移方程:
其中x要遍历所有满足flight[i][x]=1的顶点。
边界条件:对于任意的顶点i,dp(i, K-1) = 0
对于第0步,我们可以选择留在顶点0,也可以选择走到跟顶点0相邻的顶点。在考虑所有这些有可能的选择,我们求出每种选择的最优解,然后在这些最优解中找到最大值就行。
下面是我比较喜欢的递归实现。循环迭代的实现应该更优,因为递归的层数限制在数据比较大时很容易超出,而用循环可以避免这个问题。
class Solution(object):
def maxVacationDays(self, flights, days):
"""
:type flights: List[List[int]]
:type days: List[List[int]]
:rtype: int
"""
n = len(flights)
k = len(days[0])
def dp(i, j, mf):
if j==k-1:
return 0;
if (i, j) in mf:
return mf[i, j]
ans = dp(i, j+1, mf) + days[i][j+1]
for x, b in enumerate(flights[i]):
if b==1:
ans = max(ans, dp(x, j+1, mf)+days[x][j+1])
mf[i, j] = ans
return ans
mf = {}
ans = dp(0, 0, mf) + days[0][0]
for x, b in enumerate(flights[0]):
if b==1:
ans = max(ans, dp(x, 0, mf)+days[x][0])
return ans