2021-03-18 Daily-Challenge
Today I have done Maximum Score from Performing Multiplication Operations and leetcode's March LeetCoding Challenge with cpp.
Maximum Score from Performing Multiplication Operations
Description
You are given two integer arrays nums and multipliers of size n and m respectively, where n >= m. The arrays are 1-indexed.
You begin with a score of 0. You want to perform exactly m operations. On the ith operation (1-indexed), you will:
- Choose one integer
xfrom either the start or the end of the arraynums. - Add
multipliers[i] * xto your score. - Remove
xfrom the arraynums.
Return the maximum score after performing m operations.
Example 1:
Input: nums = [1,2,3], multipliers = [3,2,1]
Output: 14
Explanation: An optimal solution is as follows:
- Choose from the end, [1,2,3], adding 3 * 3 = 9 to the score.
- Choose from the end, [1,2], adding 2 * 2 = 4 to the score.
- Choose from the end, [1], adding 1 * 1 = 1 to the score.
The total score is 9 + 4 + 1 = 14.
Example 2:
Input: nums = [-5,-3,-3,-2,7,1], multipliers = [-10,-5,3,4,6]
Output: 102
Explanation: An optimal solution is as follows:
- Choose from the start, [-5,-3,-3,-2,7,1], adding -5 * -10 = 50 to the score.
- Choose from the start, [-3,-3,-2,7,1], adding -3 * -5 = 15 to the score.
- Choose from the start, [-3,-2,7,1], adding -3 * 3 = -9 to the score.
- Choose from the end, [-2,7,1], adding 1 * 4 = 4 to the score.
- Choose from the end, [-2,7], adding 7 * 6 = 42 to the score.
The total score is 50 + 15 - 9 + 4 + 42 = 102.
Constraints:
n == nums.lengthm == multipliers.length1 <= m <= 10^3m <= n <= 10^5-1000 <= nums[i], multipliers[i] <= 1000
Solution
interval dynamic programming
I first write this
class Solution {
// dp[i][j] means max score for m-th multipliers with front j elements
public:
int maximumScore(vector<int>& nums, vector<int>& multipliers) {
int m = multipliers.size();
int len = nums.size();
vector<vector<int>> dp(m + 1, vector<int>(m + 1));
for(int i = 1; i <= m; ++i) {
for(int j = 0; j <= i; ++j) {
dp[i][j] = INT_MIN;
if(j) dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + nums[j - 1] * multipliers[i - 1]);
if(j < i) dp[i][j] = max(dp[i][j], dp[i - 1][j] + nums[len - (i - j)] * multipliers[i - 1]);
// cout << i << ' ' << j << ' ' << dp[i][j] << endl;
}
}
int answer = INT_MIN;
for(int i = 0; i <= m; ++i) answer = max(answer, dp[m][i]);
return answer;
}
};
// Runtime: 528 ms, faster than 16.67% of C++ online submissions for Maximum Score from Performing Multiplication Operations.
// Memory Usage: 173.1 MB, less than 33.33% of C++ online submissions for Maximum Score from Performing Multiplication Operations.
then change vector<vector<int>> to unordered_map<unordered_map<int, int>>, but it Time Limit Exceeded, then I change it to raw array. ah ha!
class Solution {
// dp[i][j] means max score for m-th multipliers with front j elements
public:
int maximumScore(vector<int>& nums, vector<int>& multipliers) {
int m = multipliers.size();
int len = nums.size();
int dp[1001][1001] = {0};
for(int i = 1; i <= m; ++i) {
for(int j = 0; j <= i; ++j) {
dp[i][j] = INT_MIN;
if(j) dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + nums[j - 1] * multipliers[i - 1]);
if(j < i) dp[i][j] = max(dp[i][j], dp[i - 1][j] + nums[len - (i - j)] * multipliers[i - 1]);
// cout << i << ' ' << j << ' ' << dp[i][j] << endl;
}
}
int answer = INT_MIN;
for(int i = 0; i <= m; ++i) answer = max(answer, dp[m][i]);
return answer;
}
};
// Runtime: 248 ms, faster than 100.00% of C++ online submissions for Maximum Score from Performing Multiplication Operations.
// Memory Usage: 87.2 MB, less than 100.00% of C++ online submissions for Maximum Score from Performing Multiplication Operations.
March LeetCoding Challenge 18
Description
Wiggle Subsequence
Given an integer array nums, return the length of the longest wiggle sequence.
A wiggle sequence is a sequence where the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.
- For example,
[1, 7, 4, 9, 2, 5]is a wiggle sequence because the differences(6, -3, 5, -7, 3)are alternately positive and negative. - In contrast,
[1, 4, 7, 2, 5]and[1, 7, 4, 5, 5]are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.
A subsequence is obtained by deleting some elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.
Example 1:
Input: nums = [1,7,4,9,2,5]
Output: 6
Explanation: The entire sequence is a wiggle sequence.
Example 2:
Input: nums = [1,17,5,10,13,15,10,5,16,8]
Output: 7
Explanation: There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
Example 3:
Input: nums = [1,2,3,4,5,6,7,8,9]
Output: 2
Constraints:
1 <= nums.length <= 10000 <= nums[i] <= 1000
Follow up: Could you solve this in O(n) time?
Solution
it's a simple problem, but example mislead me.
template <class T>
inline constexpr int sgn(const T &a) {
return a > 0 ? 1 :
a < 0 ? -1 :
0;
}
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int len = nums.size();
if(len < 2) return len;
int pos = 1;
// all same
while(pos < len && nums[pos] == nums[pos - 1]) pos += 1;
if(pos == len) return 1;
int answer = 2;
int sign = sgn(nums[pos] - nums[pos - 1]);
pos += 1;
while(pos < len) {
while(pos < len && sgn(sign + sgn(nums[pos] - nums[pos - 1])) == sign) {
pos += 1;
}
if(pos < len) {
sign = -sign;
pos += 1;
answer += 1;
}
}
return answer;
}
};
// 26 / 26 test cases passed.
// Status: Accepted
// Runtime: 0 ms
// Memory Usage: 7 MB