2020-11-28 Daily-Challenge
Today is Saturday, I gonna review the tasks I've done this week, and finish today's leetcode's November LeetCoding Challenge with cpp
.
LeetCode Review
Monotonic Array
nothing to say
class Solution {
public:
bool isMonotonic(vector<int>& A) {
int len = A.size();
if(len < 2) return true;
int pos = 1;
while(pos < len && A[pos] == A[pos-1]) pos += 1;
if(pos == len) return true;
if(A[pos] > A[pos-1]) {
while(pos < len && A[pos] >= A[pos-1]) pos += 1;
return pos==len;
}
while(pos < len && A[pos] <= A[pos-1]) pos += 1;
return pos==len;
}
};
House Robber III
tuple is slower
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
// node -> {max money when rob house, max money when not rob house}
unordered_map<TreeNode*, tuple<int, int, int>> m;
void calc(TreeNode* root) {
if(!root || m.count(root)) return;
calc(root->left);
calc(root->right);
auto [maxRobLeft, maxNotRobLeft, maxLeft] = m[root->left];
auto [maxRobRight, maxNotRobRight, maxRight] = m[root->right];
int maxRob = root->val + maxNotRobLeft + maxNotRobRight;
int maxNotRob = maxLeft + maxRight;
m[root] = make_tuple(maxRob, maxNotRob, max(maxRob, maxNotRob));
}
public:
int rob(TreeNode* root) {
if(!root) return 0;
calc(root);
auto [a, b, answer] = m[root];
return answer;
}
};
Basic Calculator II
write more code
class Solution {
bool shouldCompute(char current, char last) {
if(current == '+' || current == '-') return true;
if(last == '*' || last == '/') return true;
return false;
}
void compute(stack<int> &n, stack<char> &op) {
int op2 = n.top();
n.pop();
int op1 = n.top();
n.pop();
int o = op.top();
op.pop();
switch(o){
case '+':
n.push(op1+op2);
break;
case '-':
n.push(op1-op2);
break;
case '*':
n.push(op1*op2);
break;
case '/':
n.push(op1/op2);
break;
}
}
public:
int calculate(string s) {
int curNum = 0;
bool inNum = false;
stack<int> n;
stack<char> op;
for(auto c : s) {
if(inNum && !isdigit(c)) {
n.push(curNum);
curNum = 0;
inNum = false;
}
if(c == ' ') continue;
if(isdigit(c)) {
curNum *= 10;
curNum += c - '0';
inNum = true;
} else {
while(op.size() && shouldCompute(c, op.top())) {
compute(n, op);
}
op.push(c);
}
}
if(inNum) n.push(curNum);
while(op.size()) {
compute(n, op);
}
return n.top();
}
};
Total Hamming Distance
seems more elegant
class Solution {
public:
int totalHammingDistance(vector<int>& nums) {
vector<int> cnt(32);
int len = nums.size();
int answer = 0;
for(int i = 0; i < len; ++i) {
for(int b = 0; b < 32; ++b) {
int have = ((nums[i] >> b) & 1);
answer += have*(i-cnt[b]) + (!have)*cnt[b];
cnt[b] += have;
}
}
return answer;
}
};
Minimum Flips to Make a OR b Equal to c
nothing to say
class Solution {
public:
int minFlips(int a, int b, int c) {
int answer = 0;
while(a || b || c) {
if(c & 1) {
answer += !((a|b)&1);
} else {
answer += (a&1) + (b&1);
}
a >>= 1;
b >>= 1;
c >>= 1;
}
return answer;
}
};
Maximum Length of Pair Chain
more elegant dp
class Solution {
public:
int findLongestChain(vector<vector<int>>& pairs) {
sort(pairs.begin(), pairs.end(), [](vector<int> &a, vector<int> &b) {
return a[1] < b[1];
});
int cur = INT_MIN;
int answer = 0;
for(auto &p : pairs) {
if(p[0] > cur) {
cur = p[1];
answer += 1;
}
}
return answer;
}
};
Longest Substring with At Least K Repeating Characters
seems $O(n \log n)$ time complexity devide-and-conquer solution
class Solution {
int helper(string &s, int begin, int end, int k) {
if(begin >= end) return 0;
int middle = (begin + end) / 2;
unordered_map<char, int> cnt, mid;
for(int i = begin; i < end; ++i) {
char c = s[i];
if(!mid.count(c) || abs(mid[c]-middle) > abs(i-middle)) mid[c] = i;
cnt[c] += 1;
}
bool ok = true;
int partitionPoint = -1;
for(auto [c, count] : cnt) {
if(count < k) {
ok = false;
if(abs(partitionPoint - middle) > abs(mid[c] - middle)) {
partitionPoint = mid[c];
}
}
}
if(ok) return end-begin;
return max(helper(s, begin, partitionPoint, k), helper(s, partitionPoint+1, end, k));
}
public:
int longestSubstring(string s, int k) {
return helper(s, 0, s.size(), k);
}
};
Remove Palindromic Subsequences
nothing to say
class Solution {
public:
int removePalindromeSub(string s) {
if(s.empty()) return 0;
int len = s.size();
for(int i = 0; 2*i < len; ++i) {
if(s[i] != s[len-1-i]) return 2;
}
return 1;
}
};
Partition Equal Subset Sum
elegant digit dp
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = accumulate(nums.begin(), nums.end(), 0, plus<int>());
if((sum & 1) || nums.empty()) return false;
bitset<20001> dp;
dp.set(0);
for(auto n : nums) {
dp |= dp << n;
}
return dp[sum/2];
}
};
Smallest Integer Divisible by K
nothing to say
class Solution {
public:
int smallestRepunitDivByK(int K) {
if(K % 2 == 0 || K % 5 == 0) return -1;
int cur = 0;
for(int i = 1; i <= K; ++i) {
cur = (cur * 10 + 1) % K;
if(cur == 0) return i;
}
// actually won't go here
return INT_MAX;
}
};
November LeetCoding Challenge 28
Description
Sliding Window Maximum
You are given an array of integers nums
, there is a sliding window of size k
which is moving from the very left of the array to the very right. You can only see the k
numbers in the window. Each time the sliding window moves right by one position.
Return the max sliding window.
Example 1:
Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Explanation:
Window position Max
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
Example 2:
Input: nums = [1], k = 1
Output: [1]
Example 3:
Input: nums = [1,-1], k = 1
Output: [1,-1]
Example 4:
Input: nums = [9,11], k = 2
Output: [11]
Example 5:
Input: nums = [4,-2], k = 2
Output: [4]
Constraints:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
Solution
monotonic queue
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
list<int> monoQueue;
int len = nums.size();
for(int i = 0; i < k; ++i) {
while(monoQueue.size() && monoQueue.back() < nums[i]) monoQueue.pop_back();
monoQueue.push_back(nums[i]);
}
vector<int> answer{monoQueue.front()};
for(int i = k; i < len; ++i) {
while(monoQueue.size() && monoQueue.back() < nums[i]) monoQueue.pop_back();
if(monoQueue.size() && monoQueue.front() == nums[i-k]) monoQueue.pop_front();
monoQueue.push_back(nums[i]);
answer.push_back(monoQueue.front());
}
return answer;
}
};