https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/
int kthSmallest(TreeNode* root, int k) {
int res;
inOrder(root, k, res);
return res;
}
void inOrder(TreeNode* node, int& k, int& res) {
if(!node) return;
if(k>0) inOrder(node->left, k, res);
k--;
if(k ==0) { res = node->val; return; }
if(k>0) inOrder(node->right, k, res);
}
Tuesday, October 31, 2017
650. 2 Keys Keyboard
https://leetcode.com/problems/2-keys-keyboard/description/
When n != 0, there the results is the sum of its prime factors.
int minSteps(int n) {
if(n == 1) return 0;
int res = 0;
vector<int> prime(n+1, 0);
for(int i=2; i<prime.size(); i++) prime[i] = i;
for(int i=2; i<prime.size(); i++) {
int p = prime[i];
if(p) {
for(int j=2*p; j<prime.size(); j+=p) prime[j] = 0;
while(n%p == 0) {
res += p;
n /= p;
}
}
}
return res;
}
When n != 0, there the results is the sum of its prime factors.
int minSteps(int n) {
if(n == 1) return 0;
int res = 0;
vector<int> prime(n+1, 0);
for(int i=2; i<prime.size(); i++) prime[i] = i;
for(int i=2; i<prime.size(); i++) {
int p = prime[i];
if(p) {
for(int j=2*p; j<prime.size(); j+=p) prime[j] = 0;
while(n%p == 0) {
res += p;
n /= p;
}
}
}
return res;
}
392. Is Subsequence
https://leetcode.com/problems/is-subsequence/description/
bool isSubsequence(string s, string t) {
if(s.empty()) return true;
int i=0, j=0;
while(j < t.size()) {
if(s[i] == t[j]) {
i++;
j++;
}
else
j++;
}
return i == s.size();
}
or
bool isSubsequence(string s, string t) {
if(s.empty()) return true;
int i=0, j=0;
for(; i<s.size(); i++) {
while(j < t.size() && s[i] != t[j]) j++;
if(j==t.size()) return false;
j++;
}
return i == s.size();
}
bool isSubsequence(string s, string t) {
if(s.empty()) return true;
int i=0, j=0;
while(j < t.size()) {
if(s[i] == t[j]) {
i++;
j++;
}
else
j++;
}
return i == s.size();
}
or
bool isSubsequence(string s, string t) {
if(s.empty()) return true;
int i=0, j=0;
for(; i<s.size(); i++) {
while(j < t.size() && s[i] != t[j]) j++;
if(j==t.size()) return false;
j++;
}
return i == s.size();
}
423. Reconstruct Original Digits from English
https://leetcode.com/problems/reconstruct-original-digits-from-english/description/
Solution 1. no need to sort. (19 ms)
string originalDigits(string s) {
string res;
vector<string> ns = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
// order to check the numbers
vector<int> order = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
// distinct char of each number
vector<char> orderc = {'z', 'w', 'u', 'x', 'g', 'o', 'r', 'f', 'v', 'i'};
vector<int> m(256,0);
vector<string> part(10,"");
for(char& c: s) m[c]++;
for(int i=0; i<10; i++) {
int n = order[i];
char key = orderc[i];
int cnt = m[key]; // count to be remove for each char in a word
for(char& c : ns[n]) m[c] -= cnt;
part[n] = string(cnt, char('0' + n));
}
for(string& p : part) res += p;
return res;
}
or,
string originalDigits(string s) {
string res;
vector<string> ns = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
vector<int> order = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
vector<char> orderc = {'z', 'w', 'u', 'x', 'g', 'o', 'r', 'f', 'v', 'i'};
vector<int> m(256,0);
for(char& c: s) m[c]++;
for(int i=0; i<10; i++) {
int n = order[i];
char key = orderc[i];
while(m[key] > 0) {
for(char& c : ns[n]) m[c]--;
res += to_string(n);
}
}
sort(res.begin(), res.end());
return res;
}
Solution 1. no need to sort. (19 ms)
string originalDigits(string s) {
string res;
vector<string> ns = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
// order to check the numbers
vector<int> order = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
// distinct char of each number
vector<char> orderc = {'z', 'w', 'u', 'x', 'g', 'o', 'r', 'f', 'v', 'i'};
vector<int> m(256,0);
vector<string> part(10,"");
for(char& c: s) m[c]++;
for(int i=0; i<10; i++) {
int n = order[i];
char key = orderc[i];
int cnt = m[key]; // count to be remove for each char in a word
for(char& c : ns[n]) m[c] -= cnt;
part[n] = string(cnt, char('0' + n));
}
for(string& p : part) res += p;
return res;
}
or,
string originalDigits(string s) {
string res;
vector<string> ns = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
vector<int> order = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};
vector<char> orderc = {'z', 'w', 'u', 'x', 'g', 'o', 'r', 'f', 'v', 'i'};
vector<int> m(256,0);
for(char& c: s) m[c]++;
for(int i=0; i<10; i++) {
int n = order[i];
char key = orderc[i];
while(m[key] > 0) {
for(char& c : ns[n]) m[c]--;
res += to_string(n);
}
}
sort(res.begin(), res.end());
return res;
}
318. Maximum Product of Word Lengths
https://leetcode.com/problems/maximum-product-of-word-lengths/description/
int maxProduct(vector<string>& words) {
int N = words.size();
int res = 0;
vector<int> w(N, 0);
for(int i=0; i<N; i++) {
for(char c : words[i]) w[i] |= 1 << (c - 'a');
for(int j=0; j<i; j++) {
if((w[j] & w[i]) == 0) {
res = max(res, (int) words[i].size() * (int) words[j].size());
}
}
}
return res;
}
int maxProduct(vector<string>& words) {
int N = words.size();
int res = 0;
vector<int> w(N, 0);
for(int i=0; i<N; i++) {
for(char c : words[i]) w[i] |= 1 << (c - 'a');
for(int j=0; j<i; j++) {
if((w[j] & w[i]) == 0) {
res = max(res, (int) words[i].size() * (int) words[j].size());
}
}
}
return res;
}
Monday, October 30, 2017
241. Different Ways to Add Parentheses
https://leetcode.com/problems/different-ways-to-add-parentheses/description/
vector<int> diffWaysToCompute(string input) {
vector<int> res;
int pos = 0;
while((pos = input.find_first_of("+-*", pos + 1)) != string::npos) {
vector<int> res1 = diffWaysToCompute(input.substr(0, pos));
vector<int> res2 = diffWaysToCompute(input.substr(pos + 1));
for(int& a : res1)
for(int& b : res2)
switch(input[pos]) {
case '+': res.push_back(a + b);
break;
case '-': res.push_back(a - b);
break;
default: res.push_back(a * b);
break;
}
}
if(res.size() == 0) res.push_back(stoi(input));
return res;
}
vector<int> diffWaysToCompute(string input) {
vector<int> res;
int pos = 0;
while((pos = input.find_first_of("+-*", pos + 1)) != string::npos) {
vector<int> res1 = diffWaysToCompute(input.substr(0, pos));
vector<int> res2 = diffWaysToCompute(input.substr(pos + 1));
for(int& a : res1)
for(int& b : res2)
switch(input[pos]) {
case '+': res.push_back(a + b);
break;
case '-': res.push_back(a - b);
break;
default: res.push_back(a * b);
break;
}
}
if(res.size() == 0) res.push_back(stoi(input));
return res;
}
lower_bound and upper_bound
Lower bound: first element that is greater-or-equal.
Upper bound: first element that is strictly greater.
Upper bound: first element that is strictly greater.
+- lb(2) == ub(2) +- lb(6) +- lb(8)
| == begin() | == ub(6) | +- ub(8) == end()
V V V V
+---+---+---+---+---+---+---+---+---+---+---+
| 3 | 4 | 4 | 4 | 4 | 5 | 7 | 7 | 7 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+---+---+
^ ^ ^
| | |
+- lb(4) +- ub(4) +- lb(9) == ub(9) == end()
|- eq-range(4) -|
Sunday, October 29, 2017
719. Find K-th Smallest Pair Distance
int smallestDistancePair(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int lo = 0, hi = nums.back() - nums.front(), mid;
while(lo<hi) {
mid = (lo + hi)/2;
// count number of distances that is <= mid;
int cnt = countDist(nums, mid);
if(cnt >= k) hi = mid;
else lo = mid + 1;
}
return lo;
}
int countDist(vector<int>& n, int dist) {
int i = 0, j = 0, cnt = 0;
for(; i < n.size(); i++) {
while(j<n.size() && n[j] - n[i] <= dist) j++;
cnt += j - i -1;
}
return cnt;
}
sort(nums.begin(), nums.end());
int lo = 0, hi = nums.back() - nums.front(), mid;
while(lo<hi) {
mid = (lo + hi)/2;
// count number of distances that is <= mid;
int cnt = countDist(nums, mid);
if(cnt >= k) hi = mid;
else lo = mid + 1;
}
return lo;
}
int countDist(vector<int>& n, int dist) {
int i = 0, j = 0, cnt = 0;
for(; i < n.size(); i++) {
while(j<n.size() && n[j] - n[i] <= dist) j++;
cnt += j - i -1;
}
return cnt;
}
Saturday, October 28, 2017
718. Maximum Length of Repeated Subarray
int findLength(vector<int>& A, vector<int>& B) {
if(A.empty() || B.empty()) return 0;
int NA = A.size(), NB = B.size();
int res = 0;
vector<int> dp(NB,0);
for(int j=0; j<NB; j++) {
if(A[0] == B[j]) {
res = 1;
dp[j] = 1;
}
}
vector<int> dp1 = dp;
for(int i=1; i<NA; i++) {
for(int j=0; j<NB; j++) {
if(A[i] == B[j]) {
if(j == 0) {
dp[j] = 1;
}
else {
dp[j] = dp1[j-1]+1;
res = max(dp[j], res);
}
}
else dp[j] = 0;
}
dp1 = dp;
}
return res;
}
if(A.empty() || B.empty()) return 0;
int NA = A.size(), NB = B.size();
int res = 0;
vector<int> dp(NB,0);
for(int j=0; j<NB; j++) {
if(A[0] == B[j]) {
res = 1;
dp[j] = 1;
}
}
vector<int> dp1 = dp;
for(int i=1; i<NA; i++) {
for(int j=0; j<NB; j++) {
if(A[i] == B[j]) {
if(j == 0) {
dp[j] = 1;
}
else {
dp[j] = dp1[j-1]+1;
res = max(dp[j], res);
}
}
else dp[j] = 0;
}
dp1 = dp;
}
return res;
}
443. String Compression
int compress(vector<char>& chars) {
if(chars.size() == 0) return 0;
chars.push_back(1);
char c_prev = 1;
int cnt = 0, k = 0;
for(int j=0; j<chars.size(); j++) {
if(chars[j] == c_prev) cnt++;
else {
if(cnt != 0) {
chars[k++] = c_prev;
if(cnt != 1) {
string s = to_string(cnt);
for(char cs: s) {
chars[k++] = cs;
}
}
}
c_prev = chars[j];
cnt = 1;
}
}
chars.pop_back();
return k;
}
if(chars.size() == 0) return 0;
chars.push_back(1);
char c_prev = 1;
int cnt = 0, k = 0;
for(int j=0; j<chars.size(); j++) {
if(chars[j] == c_prev) cnt++;
else {
if(cnt != 0) {
chars[k++] = c_prev;
if(cnt != 1) {
string s = to_string(cnt);
for(char cs: s) {
chars[k++] = cs;
}
}
}
c_prev = chars[j];
cnt = 1;
}
}
chars.pop_back();
return k;
}
717. 1-bit and 2-bit Characters
bool isOneBitCharacter(vector<int>& bits) {
if(bits.back() == 1) return false;
if(bits.size() == 1) return true;
for(int i=0; i<bits.size();) {
if(bits[i] == 1) i += 2;
else i++;
if(i == bits.size()-1) return true;
}
return false;
}
if(bits.back() == 1) return false;
if(bits.size() == 1) return true;
for(int i=0; i<bits.size();) {
if(bits[i] == 1) i += 2;
else i++;
if(i == bits.size()-1) return true;
}
return false;
}
Friday, October 27, 2017
46. Permutations
https://leetcode.com/problems/permutations/description/
Solution 1.
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
perm(nums, 0, res);
return res;
}
void perm(vector<int>& nums, int idx, vector<vector<int>>& res) {
if(idx == nums.size()) {
res.push_back(nums);
return;
}
for(int i=idx; i<nums.size(); i++) {
// 0 ~ idx-1 are fixed, swap nums[idx] with nums[idx ~ nums.size()-1]
swap(nums[idx], nums[i]);
// after swap with nums[idx], fix nums[0 ~ idx], swap for idx+1 ~ end
perm(nums, idx+1, res);
// reset before work on i+1
swap(nums[idx], nums[i]);
}
}
Solution 2.
vector<vector<int>> permute(vector<int>& nums) {
if(nums.size() == 0) return {};
vector<vector<int>> res;
res.push_back(nums);
perm(nums, res, 1);
return res;
}
void perm(vector<int>&nums, vector<vector<int>>& res, int idx) {
if(idx == nums.size()) return;
int N = res.size();
for(int j=0; j<N; j++)
for(int i=0; i<idx; i++) {
vector<int> r = res[j];
swap(r[i], r[idx]);
res.push_back(r);
}
perm(nums, res, idx+1);
}
Solution 3.
vector<vector<int>> permute(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
do {
res.push_back(nums);
} while(next_permutation(nums.begin(), nums.end()));
return res;
}
Solution 1.
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
perm(nums, 0, res);
return res;
}
void perm(vector<int>& nums, int idx, vector<vector<int>>& res) {
if(idx == nums.size()) {
res.push_back(nums);
return;
}
for(int i=idx; i<nums.size(); i++) {
// 0 ~ idx-1 are fixed, swap nums[idx] with nums[idx ~ nums.size()-1]
swap(nums[idx], nums[i]);
// after swap with nums[idx], fix nums[0 ~ idx], swap for idx+1 ~ end
perm(nums, idx+1, res);
// reset before work on i+1
swap(nums[idx], nums[i]);
}
}
Solution 2.
vector<vector<int>> permute(vector<int>& nums) {
if(nums.size() == 0) return {};
vector<vector<int>> res;
res.push_back(nums);
perm(nums, res, 1);
return res;
}
void perm(vector<int>&nums, vector<vector<int>>& res, int idx) {
if(idx == nums.size()) return;
int N = res.size();
for(int j=0; j<N; j++)
for(int i=0; i<idx; i++) {
vector<int> r = res[j];
swap(r[i], r[idx]);
res.push_back(r);
}
perm(nums, res, idx+1);
}
Solution 3.
vector<vector<int>> permute(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
do {
res.push_back(nums);
} while(next_permutation(nums.begin(), nums.end()));
return res;
}
Wednesday, October 25, 2017
715. Range Module
https://leetcode.com/problems/range-module/description/
Solution 1. Use map
class RangeModule {
map<int,int> m;
public:
RangeModule() {
}
void addRange(int left, int right) {
auto l = m.upper_bound(left), r = m.upper_bound(right);
if(l != m.begin()) {
l--;
if(l->second < left) l++;
}
if(l != r) {
left = min(left, l->first);
r--;
if(right < r->second) right = r->second;
r++;
m.erase(l,r);
}
m[left] = right;
}
bool queryRange(int left, int right) {
auto l = m.upper_bound(left);
if(l!=m.begin()) {
l--;
return l->second >= right;
}
return false;
}
void removeRange(int left, int right) {
auto l = m.upper_bound(left), r = m.upper_bound(right);
if(l != m.begin()) {
l--;
if(l->second < left) l++;
}
if(l==r) return;
int l1 = min(l->first, left);
r--;
int r1 = max(r->second, right);
r++;
m.erase(l,r);
if(l1 < left) m[l1] = left;
if(right< r1) m[right] = r1;
}
};
Solution 2. Use vector<int> (196 ms)
class RangeModule {
vector<int> v;
public:
RangeModule() {
}
void addRange(int left, int right) {
if(v.empty()) { v= {left, right}; return;}
auto l = lower_bound(v.begin(), v.end(), left);
auto r = upper_bound(v.begin(), v.end(), right);
int i = l - v.begin();
int j = r - v.begin();
if(l == r) {
if(i%2 == 0) {
l = v.insert(l, right);
v.insert(l, left);
}
return;
}
if(i%2 == 0) { *l = left; l++;}
if(j%2 == 0) { *l = right; l++; }
else { *l = *r; l++; r++;}
if(l<r) v.erase(l, r);
}
bool queryRange(int left, int right) {
// note that here l = upper_bound(..., left) and r = lower_bound(..., right)
auto l = upper_bound(v.begin(), v.end(), left);
auto r = lower_bound(v.begin(), v.end(), right);
int i = l - v.begin();
return (i%2 != 0) && l == r;
}
void removeRange(int left, int right) {
if(v.empty()) { return;}
auto l = lower_bound(v.begin(), v.end(), left);
auto r = upper_bound(v.begin(), v.end(), right);
int i = l - v.begin();
int j = r - v.begin();
if(l==r) {
if(i%2 != 0) {
l = v.insert(l, right);
v.insert(l, left);
}
return;
}
if(j%2 != 0) { r--; *r = right;}
if(i%2 != 0) { *l = left; l++;}
if(l<r) v.erase(l,r);
}
};
Solution 1. Use map
class RangeModule {
map<int,int> m;
public:
RangeModule() {
}
void addRange(int left, int right) {
auto l = m.upper_bound(left), r = m.upper_bound(right);
if(l != m.begin()) {
l--;
if(l->second < left) l++;
}
if(l != r) {
left = min(left, l->first);
r--;
if(right < r->second) right = r->second;
r++;
m.erase(l,r);
}
m[left] = right;
}
bool queryRange(int left, int right) {
auto l = m.upper_bound(left);
if(l!=m.begin()) {
l--;
return l->second >= right;
}
return false;
}
void removeRange(int left, int right) {
auto l = m.upper_bound(left), r = m.upper_bound(right);
if(l != m.begin()) {
l--;
if(l->second < left) l++;
}
if(l==r) return;
int l1 = min(l->first, left);
r--;
int r1 = max(r->second, right);
r++;
m.erase(l,r);
if(l1 < left) m[l1] = left;
if(right< r1) m[right] = r1;
}
};
class RangeModule {
vector<int> v;
public:
RangeModule() {
}
void addRange(int left, int right) {
if(v.empty()) { v= {left, right}; return;}
auto l = lower_bound(v.begin(), v.end(), left);
auto r = upper_bound(v.begin(), v.end(), right);
int i = l - v.begin();
int j = r - v.begin();
if(l == r) {
if(i%2 == 0) {
l = v.insert(l, right);
v.insert(l, left);
}
return;
}
if(i%2 == 0) { *l = left; l++;}
if(j%2 == 0) { *l = right; l++; }
else { *l = *r; l++; r++;}
if(l<r) v.erase(l, r);
}
bool queryRange(int left, int right) {
// note that here l = upper_bound(..., left) and r = lower_bound(..., right)
auto l = upper_bound(v.begin(), v.end(), left);
auto r = lower_bound(v.begin(), v.end(), right);
int i = l - v.begin();
return (i%2 != 0) && l == r;
}
void removeRange(int left, int right) {
if(v.empty()) { return;}
auto l = lower_bound(v.begin(), v.end(), left);
auto r = upper_bound(v.begin(), v.end(), right);
int i = l - v.begin();
int j = r - v.begin();
if(l==r) {
if(i%2 != 0) {
l = v.insert(l, right);
v.insert(l, left);
}
return;
}
if(j%2 != 0) { r--; *r = right;}
if(i%2 != 0) { *l = left; l++;}
if(l<r) v.erase(l,r);
}
};
713. Subarray Product Less Than K
https://leetcode.com/problems/subarray-product-less-than-k/description/
Solution 1. Count from 0 to i
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if(k==0) return 0;
int res = 0, N = nums.size();
for(int i=0, j=0, s=1; i<N; i++) {
s *= nums[i];
while(j <= i && s>=k) s /= nums[j++];
res += i-j+1;
}
return res;
}
Solution 2. Count from i to N
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if(k==0) return 0;
int res = 0, N = nums.size();
for(int i=0, j=0, s=1; i<N; i++) {
if(i > 0 && i <= j) s /= nums[i-1];
else j = i;
while(j<N && s*nums[j]<k) s *= nums[j++];
res += j-i;
}
return res;
}
Solution 1. Count from 0 to i
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if(k==0) return 0;
int res = 0, N = nums.size();
for(int i=0, j=0, s=1; i<N; i++) {
s *= nums[i];
while(j <= i && s>=k) s /= nums[j++];
res += i-j+1;
}
return res;
}
Solution 2. Count from i to N
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if(k==0) return 0;
int res = 0, N = nums.size();
for(int i=0, j=0, s=1; i<N; i++) {
if(i > 0 && i <= j) s /= nums[i-1];
else j = i;
while(j<N && s*nums[j]<k) s *= nums[j++];
res += j-i;
}
return res;
}
Monday, October 23, 2017
712. Minimum ASCII Delete Sum for Two Strings
https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/description/
Solution 1.
int minimumDeleteSum(string s1, string s2) {
int m = s1.size(), n = s2.size();
vector<vector<int>> dp(m+1, vector<int> (n+1, 0));
dp[0][0] = 0;
for(int i=1; i<m+1; i++) dp[i][0] = dp[i-1][0] + s1[i-1];
for(int j=1; j<n+1; j++) dp[0][j] = dp[0][j-1] + s2[j-1];
for(int i=1; i<m+1; i++) {
for(int j=1; j<n+1; j++) {
if(s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1];
else {
dp[i][j] = min(dp[i-1][j] + s1[i-1], dp[i][j-1] + s2[j-1]);
}
}
}
return dp[m][n];
}
Solution 1.
int minimumDeleteSum(string s1, string s2) {
int m = s1.size(), n = s2.size();
vector<vector<int>> dp(m+1, vector<int> (n+1, 0));
dp[0][0] = 0;
for(int i=1; i<m+1; i++) dp[i][0] = dp[i-1][0] + s1[i-1];
for(int j=1; j<n+1; j++) dp[0][j] = dp[0][j-1] + s2[j-1];
for(int i=1; i<m+1; i++) {
for(int j=1; j<n+1; j++) {
if(s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1];
else {
dp[i][j] = min(dp[i-1][j] + s1[i-1], dp[i][j-1] + s2[j-1]);
}
}
}
return dp[m][n];
}
714. Best Time to Buy and Sell Stock with Transaction Fee
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/description/
There could be two possible states after visiting prices[i-1]:
1. hold: there is 1 share of stock at hand. The total cash is named hold.
2. sold: there is 0 share of stock at hand. The total cash is named sold.
After visiting prices[i], the states are
1. hold = max(hold at i-1, sold at i-1 and buy 1 share at i)
2. sold = max(sold at i-1, hold at i-1 and sell 1 share at i)
int maxProfit(vector<int>& prices, int fee) {
// at i=0, the total cash at hand could be sold or hold:
int sold = 0, hold = -prices[0];
for(int i=1; i<prices.size(); i++) {
int h = max(hold, sold - prices[i]);
int s = max(sold, hold + prices[i] - fee);
sold = s;
hold = h;
}
return sold;
}
or, check local min and max
int maxProfit(vector<int>& prices, int fee) {
prices.push_back(-50000);
int hold = -prices[0], cash = 0;
for(int i=1; i<prices.size()-1; i++) {
if(prices[i]<=prices[i-1] && prices[i]<prices[i+1]) {
// local minimum
hold = max(hold, cash - prices[i]);
}
else if(prices[i]>=prices[i-1] && prices[i]>prices[i+1]) {
// local maximum
cash = max(cash, hold + prices[i] -fee);
}
}
return cash;
}
There could be two possible states after visiting prices[i-1]:
1. hold: there is 1 share of stock at hand. The total cash is named hold.
2. sold: there is 0 share of stock at hand. The total cash is named sold.
After visiting prices[i], the states are
1. hold = max(hold at i-1, sold at i-1 and buy 1 share at i)
2. sold = max(sold at i-1, hold at i-1 and sell 1 share at i)
int maxProfit(vector<int>& prices, int fee) {
// at i=0, the total cash at hand could be sold or hold:
int sold = 0, hold = -prices[0];
for(int i=1; i<prices.size(); i++) {
int h = max(hold, sold - prices[i]);
int s = max(sold, hold + prices[i] - fee);
sold = s;
hold = h;
}
return sold;
}
or, check local min and max
int maxProfit(vector<int>& prices, int fee) {
prices.push_back(-50000);
int hold = -prices[0], cash = 0;
for(int i=1; i<prices.size()-1; i++) {
if(prices[i]<=prices[i-1] && prices[i]<prices[i+1]) {
// local minimum
hold = max(hold, cash - prices[i]);
}
else if(prices[i]>=prices[i-1] && prices[i]>prices[i+1]) {
// local maximum
cash = max(cash, hold + prices[i] -fee);
}
}
return cash;
}
Friday, October 20, 2017
378. Kth Smallest Element in a Sorted Matrix
https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/
int kthSmallest(vector<vector<int>>& matrix, int k) {
int NI = matrix.size(), NJ = matrix[0].size();
int lo = matrix[0][0], hi = matrix[NI-1][NJ-1];
while(lo<hi) {
int mid = lo + (hi - lo) / 2;
int cnt = 0;
for(int i=0; i<NI; i++)
cnt += upper_bound(matrix[i].begin(), matrix[i].end(), mid)
- matrix[i].begin();
if(cnt < k) lo = mid+1;
else hi = mid;
}
return lo;
}
int kthSmallest(vector<vector<int>>& matrix, int k) {
int NI = matrix.size(), NJ = matrix[0].size();
int lo = matrix[0][0], hi = matrix[NI-1][NJ-1];
while(lo<hi) {
int mid = lo + (hi - lo) / 2;
int cnt = 0;
for(int i=0; i<NI; i++)
cnt += upper_bound(matrix[i].begin(), matrix[i].end(), mid)
- matrix[i].begin();
if(cnt < k) lo = mid+1;
else hi = mid;
}
return lo;
}
Thursday, October 19, 2017
486. Predict the Winner
https://leetcode.com/problems/predict-the-winner/description/
Solution 1. Recursion.
s1: score of player 1
s2: score of player 2
player 1's turn: t1 is true, player 1 wins if s1>=s2 for one of the two cases.
player 2's turn: t1 is false, player 1 wins if s1>=s2 for both of the two cases.
bool PredictTheWinner(vector<int>& nums) {
return predict(nums, 0, nums.size()-1, 0, 0, true);
}
bool predict(vector<int>& nums, int i, int j, int s1, int s2, bool t1) {
if(i>j) {
return s1>=s2;
}
if(t1) return predict(nums, i+1, j, s1+nums[i], s2, false)
|| predict(nums, i, j-1, s1+nums[j], s2, false);
else return predict(nums, i+1, j, s1, s2+nums[i], true)
&& predict(nums, i, j-1, s1, s2+nums[j], true);
}
Solution 2. Dynamic programming.
dp[i][j] stores the score difference between player 1 and 2, when the numbers left are from index i to j, and player 1 is the next to play. See discussion session of LeetCode.
bool PredictTheWinner(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> dp(n, vector<int> (n));
for(int i=0; i<n; i++) dp[i][i] = nums[i];
for(int j=1; j<n; j++) {
for(int i=j-1; i>=0; i--) {
dp[i][j] = max(nums[j]-dp[i][j-1], nums[i]-dp[i+1][j]);
}
}
return dp[0][n-1] >= 0;
}
Solution 1. Recursion.
s1: score of player 1
s2: score of player 2
player 1's turn: t1 is true, player 1 wins if s1>=s2 for one of the two cases.
player 2's turn: t1 is false, player 1 wins if s1>=s2 for both of the two cases.
bool PredictTheWinner(vector<int>& nums) {
return predict(nums, 0, nums.size()-1, 0, 0, true);
}
bool predict(vector<int>& nums, int i, int j, int s1, int s2, bool t1) {
if(i>j) {
return s1>=s2;
}
if(t1) return predict(nums, i+1, j, s1+nums[i], s2, false)
|| predict(nums, i, j-1, s1+nums[j], s2, false);
else return predict(nums, i+1, j, s1, s2+nums[i], true)
&& predict(nums, i, j-1, s1, s2+nums[j], true);
}
Solution 2. Dynamic programming.
dp[i][j] stores the score difference between player 1 and 2, when the numbers left are from index i to j, and player 1 is the next to play. See discussion session of LeetCode.
bool PredictTheWinner(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> dp(n, vector<int> (n));
for(int i=0; i<n; i++) dp[i][i] = nums[i];
for(int j=1; j<n; j++) {
for(int i=j-1; i>=0; i--) {
dp[i][j] = max(nums[j]-dp[i][j-1], nums[i]-dp[i+1][j]);
}
}
return dp[0][n-1] >= 0;
}
12. Integer to Roman
https://leetcode.com/problems/integer-to-roman/description/
string intToRoman(int num) {
map<int, string, greater<int>> I2R = {
{1000, "M"}, {500, "D"}, {100, "C"}, {50, "L"}, {10, "X"}, {5, "V"}, {1, "I"},
{900, "CM"}, {400, "CD"}, {90, "XC"}, {40, "XL"}, {9, "IX"}, {4, "IV"}
};
string res;
for(auto const& r : I2R) {
int c = num/r.first;
if(c==1) { res += r.second; num -= r.first;}
else if(c>1) { res += string(c, r.second[0]); num -= c*r.first;}
}
return res;
}
or,
string intToRoman(int num) {
string res;
vector<string> M = {"", "M", "MM", "MMM"};
vector<string> C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
vector<string> X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
vector<string> I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];
}
string intToRoman(int num) {
map<int, string, greater<int>> I2R = {
{1000, "M"}, {500, "D"}, {100, "C"}, {50, "L"}, {10, "X"}, {5, "V"}, {1, "I"},
{900, "CM"}, {400, "CD"}, {90, "XC"}, {40, "XL"}, {9, "IX"}, {4, "IV"}
};
string res;
for(auto const& r : I2R) {
int c = num/r.first;
if(c==1) { res += r.second; num -= r.first;}
else if(c>1) { res += string(c, r.second[0]); num -= c*r.first;}
}
return res;
}
or,
string intToRoman(int num) {
string res;
vector<string> M = {"", "M", "MM", "MMM"};
vector<string> C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
vector<string> X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
vector<string> I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];
}
481. Magical String
https://leetcode.com/problems/magical-string/description/
int magicalString(int n) {
if(n == 0) return 0;
string ms = "122";
int res = 1;
for(int i = 2; i<n; i++) {
if(ms.size()<n)
ms += string(ms[i]-'0', ms.back()=='1'? '2':'1');
res += (ms[i] == '1');
}
return res;
}
or,
int magicalString(int n) {
if(n == 0) return 0;
string ms = "122";
int res = 1;
for(int i = 2; i<n; i++) {
if(ms.size()<n)
if(ms[i] == '1') {
if(ms.back() == '1') ms += "2";
else ms += "1";
}
else {
if(ms.back() == '1') ms += "22";
else ms += "11";
}
res += (ms[i] == '1');
}
return res;
}
int magicalString(int n) {
if(n == 0) return 0;
string ms = "122";
int res = 1;
for(int i = 2; i<n; i++) {
if(ms.size()<n)
ms += string(ms[i]-'0', ms.back()=='1'? '2':'1');
res += (ms[i] == '1');
}
return res;
}
or,
int magicalString(int n) {
if(n == 0) return 0;
string ms = "122";
int res = 1;
for(int i = 2; i<n; i++) {
if(ms.size()<n)
if(ms[i] == '1') {
if(ms.back() == '1') ms += "2";
else ms += "1";
}
else {
if(ms.back() == '1') ms += "22";
else ms += "11";
}
res += (ms[i] == '1');
}
return res;
}
554. Brick Wall
https://leetcode.com/problems/brick-wall/description/
int leastBricks(vector<vector<int>>& wall) {
unordered_map<int,int> mp;
for(auto & v : wall) {
int w = 0;
for(int i=0; i<v.size()-1; i++) {
w += v[i];
mp[w]++;
}
}
int NW = wall.size(), res = NW;
for(auto &m: mp) {
int n = NW - m.second;
if(n<res) res = n;
}
return res;
}
int leastBricks(vector<vector<int>>& wall) {
unordered_map<int,int> mp;
for(auto & v : wall) {
int w = 0;
for(int i=0; i<v.size()-1; i++) {
w += v[i];
mp[w]++;
}
}
int NW = wall.size(), res = NW;
for(auto &m: mp) {
int n = NW - m.second;
if(n<res) res = n;
}
return res;
}
144. Binary Tree Preorder Traversal
https://leetcode.com/problems/binary-tree-preorder-traversal/description/
Solution 1. Recursion
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preOrder(root, res);
return res;
}
void preOrder(TreeNode* node, vector<int>& res) {
if(!node) return;
res.push_back(node->val);
preOrder(node->left, res);
preOrder(node->right, res);
}
Solution 2. Iteration
vector<int> preorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> res;
TreeNode* node;
stack<TreeNode*> st;
st.push(root);
while(!st.empty()) {
node = st.top();
res.push_back(node->val);
st.pop();
if(node->right) st.push(node->right);
if(node->left) st.push(node->left);
}
return res;
}
Solution 1. Recursion
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preOrder(root, res);
return res;
}
void preOrder(TreeNode* node, vector<int>& res) {
if(!node) return;
res.push_back(node->val);
preOrder(node->left, res);
preOrder(node->right, res);
}
Solution 2. Iteration
vector<int> preorderTraversal(TreeNode* root) {
if(!root) return {};
vector<int> res;
TreeNode* node;
stack<TreeNode*> st;
st.push(root);
while(!st.empty()) {
node = st.top();
res.push_back(node->val);
st.pop();
if(node->right) st.push(node->right);
if(node->left) st.push(node->left);
}
return res;
}
Wednesday, October 18, 2017
216. Combination Sum III
https://leetcode.com/problems/combination-sum-iii/description/
vector<vector<int>> combinationSum3(int k, int n) {
vector<vector<int>> res;
bt(k, 1, n, {}, res);
return res;
}
void bt(int k, int imin, int s, vector<int> v, vector<vector<int>>& res) {
if(s<0 || k<0) return;
if(k==0 && s==0) {
res.push_back(v);
return;
}
for(int i=imin; i<=9; i++) {
v.push_back(i);
bt(k-1, i+1, s-i, v, res);
v.pop_back();
}
}
vector<vector<int>> combinationSum3(int k, int n) {
vector<vector<int>> res;
bt(k, 1, n, {}, res);
return res;
}
void bt(int k, int imin, int s, vector<int> v, vector<vector<int>>& res) {
if(s<0 || k<0) return;
if(k==0 && s==0) {
res.push_back(v);
return;
}
for(int i=imin; i<=9; i++) {
v.push_back(i);
bt(k-1, i+1, s-i, v, res);
v.pop_back();
}
}
539. Minimum Time Difference
https://leetcode.com/problems/minimum-time-difference/description/
int findMinDifference(vector<string>& timePoints) {
sort(timePoints.begin(), timePoints.end());
int h0 = stoi(timePoints.back().substr(0,2));
int m0 = stoi(timePoints.back().substr(3));
int h1, m1, dif, res = 12*60;
for(auto &s : timePoints) {
h1 = stoi(s.substr(0,2));
m1 = stoi(s.substr(3));
dif = abs(h1*60+m1 - (h0*60+m0));
if(dif>12*60) dif = 24*60 - dif;
if(dif<res) res = dif;
h0 = h1;
m0 = m1;
}
return res;
}
int findMinDifference(vector<string>& timePoints) {
sort(timePoints.begin(), timePoints.end());
int h0 = stoi(timePoints.back().substr(0,2));
int m0 = stoi(timePoints.back().substr(3));
int h1, m1, dif, res = 12*60;
for(auto &s : timePoints) {
h1 = stoi(s.substr(0,2));
m1 = stoi(s.substr(3));
dif = abs(h1*60+m1 - (h0*60+m0));
if(dif>12*60) dif = 24*60 - dif;
if(dif<res) res = dif;
h0 = h1;
m0 = m1;
}
return res;
}
498. Diagonal Traverse
https://leetcode.com/problems/diagonal-traverse/description/
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
if(matrix.size() == 0) return {};
int M = matrix.size();
int N = matrix[0].size();
int K = M+N-2;
vector<int> res;
for(int k=0; k<=K; k++) {
int i=0, j=0, d;
if(k%2 == 0) {
i = k<M? k:M-1;
j = k-i;
d = -1;
}
else {
j = k<N? k:N-1;
i = k-j;
d = 1;
}
while(i>=0 && i<M && j>=0 && j<N) {
res.push_back(matrix[i][j]);
i += d;
j -= d;
}
}
return res;
}
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
if(matrix.size() == 0) return {};
int M = matrix.size();
int N = matrix[0].size();
int K = M+N-2;
vector<int> res;
for(int k=0; k<=K; k++) {
int i=0, j=0, d;
if(k%2 == 0) {
i = k<M? k:M-1;
j = k-i;
d = -1;
}
else {
j = k<N? k:N-1;
i = k-j;
d = 1;
}
while(i>=0 && i<M && j>=0 && j<N) {
res.push_back(matrix[i][j]);
i += d;
j -= d;
}
}
return res;
}
626. Exchange Seats
https://leetcode.com/problems/exchange-seats/description/
From the discussion section of LeetCode:
select
if(id < (select count(*) from seat), if(id mod 2=0, id-1, id+1), if(id mod 2=0, id-1, id)) as id, student
from seat
order by id;
--------
/* get all the even numbered rows as odd numbered rows */ SELECT s1.id - 1 as id, s1.student FROM Seat s1 WHERE s1.id MOD 2 = 0 UNION /* get all the odd numbered rows as even numbered rows */ SELECT s2.id + 1 as id, s2.student FROM Seat s2 WHERE s2.id MOD 2 = 1 AND s2.id != (SELECT MAX(id) FROM Seat) /* Just don't get the last row as we will handle it in the next UNION */ UNION /* get the last row if odd and don't change the id value */ SELECT s3.id, s3.student FROM Seat s3 WHERE s3.id MOD 2 = 1 AND s3.id = (SELECT MAX(id) FROM Seat) /* Order the result by id */ ORDER BY id ASC;
-------
select id, case when id%2 = 0 then (select student from seat where id = (i.id-1) ) when id%2 != 0 and id<(select count(student) from seat) then (select student from seat where id = (i.id+1) ) else student end as student from seat i
From the discussion section of LeetCode:
select
if(id < (select count(*) from seat), if(id mod 2=0, id-1, id+1), if(id mod 2=0, id-1, id)) as id, student
from seat
order by id;
--------
/* get all the even numbered rows as odd numbered rows */ SELECT s1.id - 1 as id, s1.student FROM Seat s1 WHERE s1.id MOD 2 = 0 UNION /* get all the odd numbered rows as even numbered rows */ SELECT s2.id + 1 as id, s2.student FROM Seat s2 WHERE s2.id MOD 2 = 1 AND s2.id != (SELECT MAX(id) FROM Seat) /* Just don't get the last row as we will handle it in the next UNION */ UNION /* get the last row if odd and don't change the id value */ SELECT s3.id, s3.student FROM Seat s3 WHERE s3.id MOD 2 = 1 AND s3.id = (SELECT MAX(id) FROM Seat) /* Order the result by id */ ORDER BY id ASC;
-------
select id, case when id%2 = 0 then (select student from seat where id = (i.id-1) ) when id%2 != 0 and id<(select count(student) from seat) then (select student from seat where id = (i.id+1) ) else student end as student from seat i
Subscribe to:
Posts (Atom)