Saturday, September 30, 2017
686. Repeated String Match
bool isSubStr(int n, string& A, string& B) {
if(n*A.size()<B.size()) return false;
string a = "";
for(int i=0; i<n; i++) a += A;
for(int i=0; i<A.size(); i++) {
int j;
for(j=0; j<B.size(); j++) {
if(a[i+j] != B[j]) break;
}
if(j==B.size()) return true;
}
return false;
}
int repeatedStringMatch(string A, string B) {
if(B.size() == 0) return 1;
if(A.size() == 0) return -1;
int na = A.size(), nb = B.size();
int k = nb/na;
for(int n=k; n<=k+2; n++) {
if(isSubStr(n, A, B)) return n;
}
return -1;
}
687. Longest Univalue Path
int len(TreeNode* node, int pa, int& mx) { // pa is the value of parent node
if(!node) return 0;
int l = len(node->left, node->val, mx);
int r = len(node->right, node->val,mx);
mx = max(mx, l+r);
if(node->val == pa) return 1+max(l,r);
else return 0;
}
int longestUnivaluePath(TreeNode* root) {
if(!root) return 0;
int mx = 0;
// root doesn't have parent node, pick any value that is different
len(root, root->val-1, mx);
return mx;
}
Thursday, September 28, 2017
526. Beautiful Arrangement
https://leetcode.com/problems/beautiful-arrangement/description/
void count(int N, vector<bool>& fil, int& res) {
if(N==0) {res++; return;}
for(int i=fil.size()-1; i>=0; i--) {
if(!fil[i] && (N%(i+1)==0 || (i+1)%N==0)){
fil[i] = true;
count(N-1, fil, res);
fil[i] = false;
}
}
}
int countArrangement(int N) {
int res = 0;
vector<bool> fil(N, false);
count(N, fil, res);
return res;
}
void count(int N, vector<bool>& fil, int& res) {
if(N==0) {res++; return;}
for(int i=fil.size()-1; i>=0; i--) {
if(!fil[i] && (N%(i+1)==0 || (i+1)%N==0)){
fil[i] = true;
count(N-1, fil, res);
fil[i] = false;
}
}
}
int countArrangement(int N) {
int res = 0;
vector<bool> fil(N, false);
count(N, fil, res);
return res;
}
515. Find Largest Value in Each Tree Row
https://leetcode.com/problems/find-largest-value-in-each-tree-row/description/
Solution 1. Recursion.
void levelOrder(TreeNode* node, vector<int>& res, int lev) {
if(!node) return;
if(res.size() == lev) res.push_back(node->val);
else
res[lev] = res[lev] > node->val ? res[lev] : node->val;
levelOrder(node->left, res, lev+1);
levelOrder(node->right, res, lev+1);
}
vector<int> largestValues(TreeNode* root) {
vector<int> res;
levelOrder(root, res, 0);
return res;
}
Solution 2.
vector<int> largestValues(TreeNode* root) {
vector<int> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
q.push(nullptr);
int mx = INT_MIN;
while(!q.empty()) {
TreeNode* node = q.front();
q.pop();
if(node == nullptr) {
res.push_back(mx);
mx = INT_MIN;
if(!q.empty())
q.push(nullptr);
}
else {
mx = mx>node->val ? mx : node->val;
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
}
return res;
}
Solution 1. Recursion.
void levelOrder(TreeNode* node, vector<int>& res, int lev) {
if(!node) return;
if(res.size() == lev) res.push_back(node->val);
else
res[lev] = res[lev] > node->val ? res[lev] : node->val;
levelOrder(node->left, res, lev+1);
levelOrder(node->right, res, lev+1);
}
vector<int> largestValues(TreeNode* root) {
vector<int> res;
levelOrder(root, res, 0);
return res;
}
Solution 2.
vector<int> largestValues(TreeNode* root) {
vector<int> res;
if(!root) return res;
queue<TreeNode*> q;
q.push(root);
q.push(nullptr);
int mx = INT_MIN;
while(!q.empty()) {
TreeNode* node = q.front();
q.pop();
if(node == nullptr) {
res.push_back(mx);
mx = INT_MIN;
if(!q.empty())
q.push(nullptr);
}
else {
mx = mx>node->val ? mx : node->val;
if(node->left) q.push(node->left);
if(node->right) q.push(node->right);
}
}
return res;
}
553. Optimal Division
https://leetcode.com/problems/optimal-division/description/
string optimalDivision(vector<int>& nums) {
if(nums.size()==0) return "";
if(nums.size()==1) return to_string(nums[0]);
string res = to_string(nums[0]);
if(nums.size()==2) return res+"/"+to_string(nums[1]);
res += "/(";
for(int i=1; i<nums.size(); i++) {
res += to_string(nums[i]) + "/";
}
res[res.size()-1] = ')';
return res;
}
string optimalDivision(vector<int>& nums) {
if(nums.size()==0) return "";
if(nums.size()==1) return to_string(nums[0]);
string res = to_string(nums[0]);
if(nums.size()==2) return res+"/"+to_string(nums[1]);
res += "/(";
for(int i=1; i<nums.size(); i++) {
res += to_string(nums[i]) + "/";
}
res[res.size()-1] = ')';
return res;
}
647. Palindromic Substrings
https://leetcode.com/problems/palindromic-substrings/description/
Solution 1. Moving the center of the palindrome and count.
int countSubstrings(string s) {
int n = s.size();
int res = 0;
for(int i=0; i<n; i++) {
for(int j=0; i-j>=0 && i+j<n; j++) {
if(s[i-j] == s[i+j]) res++;
else break;
}
for(int j=0; i-j>=0 && i+j+1<n; j++) {
if(s[i-j] == s[i+j+1]) res++;
else break;
}
}
return res;
}
Solution 2. Recursion. Slow because of duplicated comparisons.
int count(string& s, int n) {
if(n<2) return n;
int m = count(s, n-1);
for(int lo = 0; lo<n; lo++) {
int i=lo, j = n-1;
for(; i<=j; i++, j--) {
if(s[i]!=s[j]) break;
}
m += i>j;
}
return m;
}
int countSubstrings(string s) {
return count(s, s.size());
}
Solution 1. Moving the center of the palindrome and count.
int countSubstrings(string s) {
int n = s.size();
int res = 0;
for(int i=0; i<n; i++) {
for(int j=0; i-j>=0 && i+j<n; j++) {
if(s[i-j] == s[i+j]) res++;
else break;
}
for(int j=0; i-j>=0 && i+j+1<n; j++) {
if(s[i-j] == s[i+j+1]) res++;
else break;
}
}
return res;
}
Solution 2. Recursion. Slow because of duplicated comparisons.
int count(string& s, int n) {
if(n<2) return n;
int m = count(s, n-1);
for(int lo = 0; lo<n; lo++) {
int i=lo, j = n-1;
for(; i<=j; i++, j--) {
if(s[i]!=s[j]) break;
}
m += i>j;
}
return m;
}
int countSubstrings(string s) {
return count(s, s.size());
}
540. Single Element in a Sorted Array
https://leetcode.com/problems/single-element-in-a-sorted-array/description/
int singleNonDuplicate(vector<int>& nums) {
for(int i=1;i<nums.size();i+=2) {
if(nums[i] != nums[i-1]) return nums[i-1];
}
return nums.back();
}
or use XOR
int singleNonDuplicate(vector<int>& nums) {
int res = 0;
for(int n : nums) {
res ^= n;
}
return res;
}
int singleNonDuplicate(vector<int>& nums) {
for(int i=1;i<nums.size();i+=2) {
if(nums[i] != nums[i-1]) return nums[i-1];
}
return nums.back();
}
or use XOR
int singleNonDuplicate(vector<int>& nums) {
int res = 0;
for(int n : nums) {
res ^= n;
}
return res;
}
406. Queue Reconstruction by Height
https://leetcode.com/problems/queue-reconstruction-by-height/description/
Solution 1. Sort and insert
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
vector<pair<int, int>> res;
sort(people.begin(), people.end(),
[&](pair<int, int> a, pair<int, int> b){
if(a.first!=b.first)return a.first>b.first;
else return a.second<b.second;
});
for(int i=0; i<people.size(); i++) {
res.insert(res.begin()+people[i].second, people[i]);
}
return res;
}
The sort could be:
auto comp = [](const pair<int, int>& p1, const pair<int, int>& p2) {
Solution 1. Sort and insert
vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) {
vector<pair<int, int>> res;
sort(people.begin(), people.end(),
[&](pair<int, int> a, pair<int, int> b){
if(a.first!=b.first)return a.first>b.first;
else return a.second<b.second;
});
for(int i=0; i<people.size(); i++) {
res.insert(res.begin()+people[i].second, people[i]);
}
return res;
}
The sort could be:
auto comp = [](const pair<int, int>& p1, const pair<int, int>& p2) {
return p1.first > p2.first || (p1.first == p2.first && p1.second < p2.second);
};
sort(people.begin(), people.end(), comp);
Wednesday, September 27, 2017
442. Find All Duplicates in an Array
https://leetcode.com/problems/find-all-duplicates-in-an-array/description/
Solution 1. swap number i to index i-1
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
int i=0;
while(i<nums.size()) {
if(nums[i] != nums[nums[i]-1])
swap(nums[i], nums[nums[i]-1]);
else i++;
}
for(int i=0; i<nums.size(); i++) {
if(i+1 != nums[i]) res.push_back(nums[i]);
}
return res;
}
Solution 2. Mark by +/-
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
for(int i=0; i<nums.size(); i++) {
nums[abs(nums[i])-1] = -nums[abs(nums[i])-1];
if(nums[abs(nums[i])-1]>0) res.push_back(abs(nums[i]));
}
return res;
}
Solution 3. counting number nums[i] by adding n to index i-1
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
int n = nums.size();
for(int i=0; i<n; i++) {
nums[(nums[i]-1)%n] += n;
}
for(int i=0; i<n; i++) {
if(nums[i]>2*n) res.push_back(i+1);
}
return res;
}
Solution 1. swap number i to index i-1
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
int i=0;
while(i<nums.size()) {
if(nums[i] != nums[nums[i]-1])
swap(nums[i], nums[nums[i]-1]);
else i++;
}
for(int i=0; i<nums.size(); i++) {
if(i+1 != nums[i]) res.push_back(nums[i]);
}
return res;
}
Solution 2. Mark by +/-
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
for(int i=0; i<nums.size(); i++) {
nums[abs(nums[i])-1] = -nums[abs(nums[i])-1];
if(nums[abs(nums[i])-1]>0) res.push_back(abs(nums[i]));
}
return res;
}
Solution 3. counting number nums[i] by adding n to index i-1
vector<int> findDuplicates(vector<int>& nums) {
vector<int> res;
int n = nums.size();
for(int i=0; i<n; i++) {
nums[(nums[i]-1)%n] += n;
}
for(int i=0; i<n; i++) {
if(nums[i]>2*n) res.push_back(i+1);
}
return res;
}
513. Find Bottom Left Tree Value
https://leetcode.com/problems/find-bottom-left-tree-value/description/
Solution 1
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> q;
q.push(root);
q.push(nullptr);
int res;
TreeNode* last = nullptr;
while(q.size()>1) {
if(last == nullptr) res = q.front()->val;
last = q.front();
q.pop();
if(last == nullptr) {
q.push(nullptr);
}
else {
if(last->left) q.push(last->left);
if(last->right) q.push(last->right);
}
}
return res;
}
Solution 2. Recursion
void findLeft(TreeNode* node, int& mx, int& maxDep, int dep) {
if(!node) return;
if(maxDep < dep) {
maxDep = dep;
mx = node->val;
}
findLeft(node->left, mx, maxDep, dep+1);
findLeft(node->right, mx, maxDep, dep+1);
}
int findBottomLeftValue(TreeNode* root) {
int mx = root->val, maxDep = 0;
findLeft(root, mx, maxDep, 0);
return mx;
}
Solution 1
int findBottomLeftValue(TreeNode* root) {
queue<TreeNode*> q;
q.push(root);
q.push(nullptr);
int res;
TreeNode* last = nullptr;
while(q.size()>1) {
if(last == nullptr) res = q.front()->val;
last = q.front();
q.pop();
if(last == nullptr) {
q.push(nullptr);
}
else {
if(last->left) q.push(last->left);
if(last->right) q.push(last->right);
}
}
return res;
}
Solution 2. Recursion
void findLeft(TreeNode* node, int& mx, int& maxDep, int dep) {
if(!node) return;
if(maxDep < dep) {
maxDep = dep;
mx = node->val;
}
findLeft(node->left, mx, maxDep, dep+1);
findLeft(node->right, mx, maxDep, dep+1);
}
int findBottomLeftValue(TreeNode* root) {
int mx = root->val, maxDep = 0;
findLeft(root, mx, maxDep, 0);
return mx;
}
338. Counting Bits
https://leetcode.com/problems/counting-bits/description/
vector<int> countBits(int num) {
vector<int> res;
for(int i=0; i<=num; i++) {
int n = i;
int b = 0;
while(n) {
b += n&1;
n >>= 1;
}
res.push_back(b);
}
return res;
}
vector<int> countBits(int num) {
vector<int> res;
for(int i=0; i<=num; i++) {
int n = i;
int b = 0;
while(n) {
b += n&1;
n >>= 1;
}
res.push_back(b);
}
return res;
}
419. Battleships in a Board
https://leetcode.com/problems/battleships-in-a-board/description/
int countBattleships(vector<vector<char>>& board) {
int res = 0;
for(int i=0; i<board.size(); i++)
for(int j=0; j<board[0].size(); j++) {
if(board[i][j] == 'X') {
if(i!=0 && j!=0)
res += (board[i-1][j] != 'X' && board[i][j-1] != 'X');
else if(i==0 && j!=0)
res += (board[i][j-1] != 'X');
else if(i!=0 && j==0)
res += (board[i-1][j] != 'X');
else res++;
}
}
return res;
}
int countBattleships(vector<vector<char>>& board) {
int res = 0;
for(int i=0; i<board.size(); i++)
for(int j=0; j<board[0].size(); j++) {
if(board[i][j] == 'X') {
if(i!=0 && j!=0)
res += (board[i-1][j] != 'X' && board[i][j-1] != 'X');
else if(i==0 && j!=0)
res += (board[i][j-1] != 'X');
else if(i!=0 && j==0)
res += (board[i-1][j] != 'X');
else res++;
}
}
return res;
}
537. Complex Number Multiplication
https://leetcode.com/problems/complex-number-multiplication/description/
Solution 1.stringstream
string complexNumberMultiply(string a, string b) {
int ar, ai, br, bi;
char buff;
stringstream ssa(a), ssb(b), res;
ssa >> ar >> buff >> ai >> buff;
ssb >> br >> buff >> bi >> buff;
res << ar*br - ai*bi << "+" << ar*bi + br*ai << "i";
return res.str();
}
Solution 2. strtok
string complexNumberMultiply(string a, string b) {
string ars = strtok((char*)a.c_str(), "+i");
string ais = strtok(NULL, "+i");
string brs = strtok((char*)b.c_str(), "+i");
string bis = strtok(NULL, "+i");
long ar = stol(ars);
long ai = stol(ais);
long br = stol(brs);
long bi = stol(bis);
long re = ar*br - ai*bi;
long im = ar*bi + ai*br;
return to_string(re)+"+"+to_string(im)+"i";
}
Solution 1.stringstream
string complexNumberMultiply(string a, string b) {
int ar, ai, br, bi;
char buff;
stringstream ssa(a), ssb(b), res;
ssa >> ar >> buff >> ai >> buff;
ssb >> br >> buff >> bi >> buff;
res << ar*br - ai*bi << "+" << ar*bi + br*ai << "i";
return res.str();
}
Solution 2. strtok
string complexNumberMultiply(string a, string b) {
string ars = strtok((char*)a.c_str(), "+i");
string ais = strtok(NULL, "+i");
string brs = strtok((char*)b.c_str(), "+i");
string bis = strtok(NULL, "+i");
long ar = stol(ars);
long ai = stol(ais);
long br = stol(brs);
long bi = stol(bis);
long re = ar*br - ai*bi;
long im = ar*bi + ai*br;
return to_string(re)+"+"+to_string(im)+"i";
}
654. Maximum Binary Tree
https://leetcode.com/problems/maximum-binary-tree/description/
Solution 1.
use a vector to keep part of tree nodes in decreasing order.
keep popping the vector until empty or a bigger number.
The bigger number (if exists) is current number's root, and the last popped number (if exist) is current number's right child and it is the parent of the number before last popped.
push current number into the vector.
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
vector<TreeNode*> v;
for(int n : nums) {
TreeNode* node = new TreeNode(n);
while(!v.empty() && v.back()->val<n) {
node->left = v.back();
v.pop_back();
}
if(!v.empty()) v.back()->right = node;
v.push_back(node);
}
return v.front();
}
Solution 2. Recursion
TreeNode* construct(vector<int>& nums, int lo, int hi) {
if(lo>hi) return nullptr;
int mx = nums[lo], ix = lo;
for(int i=lo+1; i<=hi;i++) if(nums[i]>mx) {
mx = nums[i];
ix = i;
}
TreeNode* node = new TreeNode(mx);
node->left = construct(nums, lo, ix-1);
node->right = construct(nums, ix+1, hi);
return node;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return construct(nums, 0, nums.size()-1);
}
Solution 1.
use a vector to keep part of tree nodes in decreasing order.
keep popping the vector until empty or a bigger number.
The bigger number (if exists) is current number's root, and the last popped number (if exist) is current number's right child and it is the parent of the number before last popped.
push current number into the vector.
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
vector<TreeNode*> v;
for(int n : nums) {
TreeNode* node = new TreeNode(n);
while(!v.empty() && v.back()->val<n) {
node->left = v.back();
v.pop_back();
}
if(!v.empty()) v.back()->right = node;
v.push_back(node);
}
return v.front();
}
Solution 2. Recursion
TreeNode* construct(vector<int>& nums, int lo, int hi) {
if(lo>hi) return nullptr;
int mx = nums[lo], ix = lo;
for(int i=lo+1; i<=hi;i++) if(nums[i]>mx) {
mx = nums[i];
ix = i;
}
TreeNode* node = new TreeNode(mx);
node->left = construct(nums, lo, ix-1);
node->right = construct(nums, ix+1, hi);
return node;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return construct(nums, 0, nums.size()-1);
}
535. Encode and Decode TinyURL
https://leetcode.com/problems/encode-and-decode-tinyurl/description/
class Solution {
unordered_map<string, string> encodeMap;
unordered_map<string, string> decodeMap;
string dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public:
// Encodes a URL to a shortened URL.
string encode(string longUrl) {
if(encodeMap.count(longUrl)) return encodeMap[longUrl];
string shortUrl = "http://tinyurl.com/";
int n = encodeMap.size(), nd = dict.size();
while(n) {
shortUrl += dict[n%nd];
n /= nd;
}
encodeMap[longUrl] = shortUrl;
decodeMap[shortUrl] = longUrl;
return shortUrl;
}
// Decodes a shortened URL to its original URL.
string decode(string shortUrl) {
return decodeMap[shortUrl];
}
};
class Solution {
unordered_map<string, string> encodeMap;
unordered_map<string, string> decodeMap;
string dict = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public:
// Encodes a URL to a shortened URL.
string encode(string longUrl) {
if(encodeMap.count(longUrl)) return encodeMap[longUrl];
string shortUrl = "http://tinyurl.com/";
int n = encodeMap.size(), nd = dict.size();
while(n) {
shortUrl += dict[n%nd];
n /= nd;
}
encodeMap[longUrl] = shortUrl;
decodeMap[shortUrl] = longUrl;
return shortUrl;
}
// Decodes a shortened URL to its original URL.
string decode(string shortUrl) {
return decodeMap[shortUrl];
}
};
176. Second Highest Salary
https://leetcode.com/problems/second-highest-salary/description/
select max(Salary) as SecondHighestSalary
from Employee
where Salary < (select max(Salary) from Employee)
select (
select distinct Salary from Employee order by Salary Desc limit 1 offset 1
) as SecondHighestSalary
select max(Salary) as SecondHighestSalary
from Employee
where Salary < (select max(Salary) from Employee)
select (
select distinct Salary from Employee order by Salary Desc limit 1 offset 1
) as SecondHighestSalary
665. Non-decreasing Array
https://leetcode.com/problems/non-decreasing-array/description/
bool checkPossibility(vector<int>& nums) {
nums.insert(nums.begin(), INT_MIN);
nums.push_back(INT_MAX);
int dec = 0, idx = -1;
for(int i=1; i<nums.size(); i++) {
if(nums[i-1]>nums[i]) {
dec++;
if(dec == 1) idx = i;
}
if(dec>1) return false;
}
if(dec == 1)
return (idx>1 && nums[idx]>=nums[idx-2])
|| (idx+1<nums.size() && nums[idx+1]>=nums[idx-1]);
return true;
}
bool checkPossibility(vector<int>& nums) {
nums.insert(nums.begin(), INT_MIN);
nums.push_back(INT_MAX);
int dec = 0, idx = -1;
for(int i=1; i<nums.size(); i++) {
if(nums[i-1]>nums[i]) {
dec++;
if(dec == 1) idx = i;
}
if(dec>1) return false;
}
if(dec == 1)
return (idx>1 && nums[idx]>=nums[idx-2])
|| (idx+1<nums.size() && nums[idx+1]>=nums[idx-1]);
return true;
}
196. Delete Duplicate Emails
https://leetcode.com/problems/delete-duplicate-emails/description/
delete p1
from Person p1, Person p2
where p1.Email = p2.Email
and p1.Id > p2.Id
Solution 2.
delete from Person where id not in( select t.id from ( select min(id) as id from Person group by email ) t )
delete p1
from Person p1, Person p2
where p1.Email = p2.Email
and p1.Id > p2.Id
Solution 2.
delete from Person where id not in( select t.id from ( select min(id) as id from Person group by email ) t )
Tuesday, September 26, 2017
479. Largest Palindrome Product
https://leetcode.com/problems/largest-palindrome-product/description/
long getCandidate(int n) {
string s = to_string(n);
reverse(s.begin(), s.end());
return stol(to_string(n) + s);
}
int largestPalindrome(int n) {
if(n==1) return 9;
int mx = pow(10,n) - 1;
int mi = pow(10,n-1);
for(int i=mx; i>=mi; i--) {
long c = getCandidate(i);
for(long j=mx; j*j>=c; j--) {
if(c%j == 0 && c/j >= mi) {
return c%1337;
}
}
}
return -1;
}
long getCandidate(int n) {
string s = to_string(n);
reverse(s.begin(), s.end());
return stol(to_string(n) + s);
}
int largestPalindrome(int n) {
if(n==1) return 9;
int mx = pow(10,n) - 1;
int mi = pow(10,n-1);
for(int i=mx; i>=mi; i--) {
long c = getCandidate(i);
for(long j=mx; j*j>=c; j--) {
if(c%j == 0 && c/j >= mi) {
return c%1337;
}
}
}
return -1;
}
Saturday, September 23, 2017
682. Baseball Game
int calPoints(vector<string>& ops) {
int res = 0;
stack<int> pts;
for(int i=0; i<ops.size(); i++) { // initialize i = 0
if(ops[i] == "C") {
int s = pts.top();
res -= s;
pts.pop();
}
else if(ops[i] == "D") {
int s = 2 * pts.top();
res += s;
pts.push(s);
}
else if(ops[i] == "+") {
int s1 = pts.top();
pts.pop();
int s2 = pts.top() + s1;
res += s2;
pts.push(s1);
pts.push(s2);
}
else {
int s = atoi(ops[i].c_str());
res += s;
pts.push(s);
}
}
return res;
}
681. Next Closest Time
bool isValid(string time) {
if(stoi(time.substr(0,2))>23) return false;
if(stoi(time.substr(3,2))>59) return false;
return true;
}
string nextClosestTime(string time) {
string t = time;
string s = {t[0], t[1], t[3], t[4]};
vector<string> v;
for(int i=0; i<4; i++)
for(int j=0; j<4; j++)
for(int k=0; k<4; k++)
for(int l=0; l<4; l++) {
t[0] = s[i], t[1] = s[j], t[3] = s[k], t[4] = s[l];
if(isValid(t)) v.push_back(t);
}
sort(v.begin(), v.end());
auto last = unique(v.begin(), v.end());
v.erase(last, v.end());
auto it = find(v.begin(), v.end(), time);
if(it+1 == v.end()) return *v.begin();
else return *(it+1);
}
Friday, September 22, 2017
7. Reverse Integer
https://leetcode.com/problems/reverse-integer/description/
int reverse(int x) {
if(x == INT_MIN) return 0;
if(x < 0) return -reverse(-x);
int res = 0;
while(x) {
int r = x%10;
if(res > INT_MAX/10) return 0;
res = res * 10 + r;
x /= 10;
}
return res;
}
int reverse(int x) {
if(x == INT_MIN) return 0;
if(x < 0) return -reverse(-x);
int res = 0;
while(x) {
int r = x%10;
if(res > INT_MAX/10) return 0;
res = res * 10 + r;
x /= 10;
}
return res;
}
193. Valid Phone Numbers
https://leetcode.com/problems/valid-phone-numbers/description/
^ start with
$ end with
basic regex
( { | are regular characters matching ( { |
\( \{ \| ... are special operations
grep '^\([0-9]\{3\}-\|([0-9]\{3\}) \)[0-9]\{3\}-[0-9]\{4\}$' file.txt
extended regex
( { | are special operations
\( \{ \| ... are escape characters matching ( { |
grep -E '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt
^ start with
$ end with
basic regex
( { | are regular characters matching ( { |
\( \{ \| ... are special operations
grep '^\([0-9]\{3\}-\|([0-9]\{3\}) \)[0-9]\{3\}-[0-9]\{4\}$' file.txt
extended regex
( { | are special operations
\( \{ \| ... are escape characters matching ( { |
grep -E '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt
Thursday, September 21, 2017
189. Rotate Array
https://leetcode.com/problems/rotate-array/description/
Solution 1. O(1) space, 3 reversions
void rotate(vector<int>& nums, int k) {
int N = nums.size();
if(N ==0 || k%N ==0) return;
k = k%N;
reverse(begin(nums), begin(nums)+N-k);
reverse(begin(nums)+N-k, end(nums));
reverse(begin(nums), end(nums));
}
Solution 2. O(1) space, keep rotating one by one until total number of rotating = nums.size()
void rotate1(vector<int>& nums, int k) {
int N = nums.size();
if(N ==0 || k%N ==0) return;
k = k%N;
int cnt = 0, iStart = 0, iCurrt = 0, numRot = nums[0], tmp;
while(cnt<N) {
do{
iCurrt = (iCurrt + k)%N;
tmp = nums[iCurrt];
nums[iCurrt] = numRot;
numRot = tmp;
cnt++;
}while(iStart != iCurrt);
iStart++;
iCurrt = iStart;
numRot = nums[iCurrt];
}
}
Solution 3.
void rotate(vector<int>& nums, int k) {
int N = nums.size();
k = k%N;
if(k == 0) return;
vector<int> nk(k);
for(int i=0; i<k; i++) nk[i] = nums[N-k+i];
for(int i=N-k-1; i>=0; i--) {
nums[i+k] = nums[i];
}
for(int i=0; i<k; i++) nums[i] = nk[i];
}
Solution 1. O(1) space, 3 reversions
void rotate(vector<int>& nums, int k) {
int N = nums.size();
if(N ==0 || k%N ==0) return;
k = k%N;
reverse(begin(nums), begin(nums)+N-k);
reverse(begin(nums)+N-k, end(nums));
reverse(begin(nums), end(nums));
}
Solution 2. O(1) space, keep rotating one by one until total number of rotating = nums.size()
void rotate1(vector<int>& nums, int k) {
int N = nums.size();
if(N ==0 || k%N ==0) return;
k = k%N;
int cnt = 0, iStart = 0, iCurrt = 0, numRot = nums[0], tmp;
while(cnt<N) {
do{
iCurrt = (iCurrt + k)%N;
tmp = nums[iCurrt];
nums[iCurrt] = numRot;
numRot = tmp;
cnt++;
}while(iStart != iCurrt);
iStart++;
iCurrt = iStart;
numRot = nums[iCurrt];
}
}
Solution 3.
void rotate(vector<int>& nums, int k) {
int N = nums.size();
k = k%N;
if(k == 0) return;
vector<int> nk(k);
for(int i=0; i<k; i++) nk[i] = nums[N-k+i];
for(int i=N-k-1; i>=0; i--) {
nums[i+k] = nums[i];
}
for(int i=0; i<k; i++) nums[i] = nk[i];
}
Wednesday, September 20, 2017
596. Classes More Than 5 Students
https://leetcode.com/problems/classes-more-than-5-students/description/
select class
from courses
group by class
having count(distinct student) > 4
select class
from courses
group by class
having count(distinct student) > 4
278. First Bad Version
https://leetcode.com/problems/first-bad-version/description/
int firstBadVersion(int n) {
int lo = 1, hi = n;
while(lo<hi){
int mid = lo +(hi - lo)/2;
if(isBadVersion(mid)) hi = mid;
else lo = mid + 1;
}
return lo;
}
int firstBadVersion(int n) {
int lo = 1, hi = n;
while(lo<hi){
int mid = lo +(hi - lo)/2;
if(isBadVersion(mid)) hi = mid;
else lo = mid + 1;
}
return lo;
}
168. Excel Sheet Column Title
https://leetcode.com/problems/excel-sheet-column-title/description/
string convertToTitle(int n) {
string s = "";
while(n) {
n--;
s = char('A' + n%26) + s;
n /= 26;
}
return s;
}
string convertToTitle(int n) {
string s = "";
while(n) {
n--;
s = char('A' + n%26) + s;
n /= 26;
}
return s;
}
Tuesday, September 19, 2017
125. Valid Palindrome
https://leetcode.com/problems/valid-palindrome/description/
bool isPalindrome(string s) {
if(s.size()<2) return true;
for(int i=0, j=s.size()-1; i<j;) {
char a = tolower(s[i]);
char b = tolower(s[j]);
if(!(a>='a'&&a<='z') && !(a>='0'&&a<='9')) { i++; continue;}
if(!(b>='a'&&b<='z') && !(b>='0'&&b<='9')) { j--; continue;}
if(a!=b) return false;
i++;
j--;
}
return true;
}
bool isPalindrome(string s) {
if(s.size()<2) return true;
for(int i=0, j=s.size()-1; i<j;) {
char a = tolower(s[i]);
char b = tolower(s[j]);
if(!(a>='a'&&a<='z') && !(a>='0'&&a<='9')) { i++; continue;}
if(!(b>='a'&&b<='z') && !(b>='0'&&b<='9')) { j--; continue;}
if(a!=b) return false;
i++;
j--;
}
return true;
}
204. Count Primes
https://leetcode.com/problems/count-primes/description/
Solution 1. Use Sieve of Eratosthenes (13 ms)
int countPrimes(int n) {
if(n<=2) return 0;
bool s[n] = {false}; // faster than vector<bool> s(n,false);
int np = 1;
for(int i=3; i<n; i+=2) {
if(!s[i]) {
np++;
if(i>n/i) continue;
for(int j=i*i, step=i<<1; j<n; j+=step) {
//set step = 2*i to ignore even numbers
s[j] = true;
}
}
}
return np;
}
Solution 1. Use Sieve of Eratosthenes (13 ms)
int countPrimes(int n) {
if(n<=2) return 0;
bool s[n] = {false}; // faster than vector<bool> s(n,false);
int np = 1;
for(int i=3; i<n; i+=2) {
if(!s[i]) {
np++;
if(i>n/i) continue;
for(int j=i*i, step=i<<1; j<n; j+=step) {
//set step = 2*i to ignore even numbers
s[j] = true;
}
}
}
return np;
}
414. Third Maximum Number
https://leetcode.com/problems/third-maximum-number/description/
Solution 1. Use a set
int thirdMax(vector<int>& nums) {
set<int> top3;
for(int n:nums){
if(top3.size()<3 || n> *top3.begin())
top3.insert(n);
if(top3.size()>3) top3.erase(top3.begin());
}
return (top3.size() == 3) ? *top3.begin() : *top3.rbegin();
}
Solution 2. Use pointers
int thirdMax(vector<int>& nums) {
int *p1 = &nums[0], *p2 = nullptr, *p3 = nullptr;
for(int i=0; i<nums.size(); i++) {
if(nums[i] > *p1) {
p3 = p2;
p2 = p1;
p1 = &nums[i];
}
else if(nums[i] == *p1) continue;
else if(!p2) p2 = &nums[i];
else if(nums[i] < *p1 && nums[i] > *p2) {
p3 = p2;
p2 = &nums[i];
}
else if(nums[i] == *p2) continue;
else if(!p3) p3 = &nums[i];
else if(nums[i] < *p2 && nums[i] > *p3 ) {
p3 = &nums[i];
}
}
if(p3) return *p3;
else return *p1;
}
Solution 3
int thirdMax(vector<int>& nums) {
int m1 = INT_MIN, m2 = INT_MIN, m3 = INT_MIN, i = 0;
for(int n : nums) {
if(n > m1) {
m3 = m2;
m2 = m1;
m1 = n;
i++;
}
else if(n < m1 && n > m2) {
m3 = m2;
m2 = n;
i++;
}
else if(n < m2 && n > m3 ) {
m3 = n;
i++;
}
else if(n == INT_MIN) i++;
}
if(m1>m2 && m2>m3 && i>=3) return m3;
else return m1;
}
Solution 1. Use a set
int thirdMax(vector<int>& nums) {
set<int> top3;
for(int n:nums){
if(top3.size()<3 || n> *top3.begin())
top3.insert(n);
if(top3.size()>3) top3.erase(top3.begin());
}
return (top3.size() == 3) ? *top3.begin() : *top3.rbegin();
}
Solution 2. Use pointers
int thirdMax(vector<int>& nums) {
int *p1 = &nums[0], *p2 = nullptr, *p3 = nullptr;
for(int i=0; i<nums.size(); i++) {
if(nums[i] > *p1) {
p3 = p2;
p2 = p1;
p1 = &nums[i];
}
else if(nums[i] == *p1) continue;
else if(!p2) p2 = &nums[i];
else if(nums[i] < *p1 && nums[i] > *p2) {
p3 = p2;
p2 = &nums[i];
}
else if(nums[i] == *p2) continue;
else if(!p3) p3 = &nums[i];
else if(nums[i] < *p2 && nums[i] > *p3 ) {
p3 = &nums[i];
}
}
if(p3) return *p3;
else return *p1;
}
Solution 3
int thirdMax(vector<int>& nums) {
int m1 = INT_MIN, m2 = INT_MIN, m3 = INT_MIN, i = 0;
for(int n : nums) {
if(n > m1) {
m3 = m2;
m2 = m1;
m1 = n;
i++;
}
else if(n < m1 && n > m2) {
m3 = m2;
m2 = n;
i++;
}
else if(n < m2 && n > m3 ) {
m3 = n;
i++;
}
else if(n == INT_MIN) i++;
}
if(m1>m2 && m2>m3 && i>=3) return m3;
else return m1;
}
Monday, September 18, 2017
69. Sqrt(x)
https://leetcode.com/problems/sqrtx/description/
Solution 1.
int mySqrt(int x) {
if(x == 0) return 0;
int n = 0;
for(int m = 1<<30; m!=0; m>>=1){
int r = n|m;
while(r>x/r) {
m >>= 1;
r = n|m;
}
n |= m;
}
return n;
}
Solution 2
int mySqrt(int x) {
if(x == 0) return 0;
double y = log10(x)/2.;
return (int) pow(10.,y);
}
Solution 1.
int mySqrt(int x) {
if(x == 0) return 0;
int n = 0;
for(int m = 1<<30; m!=0; m>>=1){
int r = n|m;
while(r>x/r) {
m >>= 1;
r = n|m;
}
n |= m;
}
return n;
}
Solution 2
int mySqrt(int x) {
if(x == 0) return 0;
double y = log10(x)/2.;
return (int) pow(10.,y);
}
532. K-diff Pairs in an Array
https://leetcode.com/problems/k-diff-pairs-in-an-array/description/
int findPairs(vector<int>& nums, int k) {
if(k<0) return 0;
unordered_map<int,int> mp;
int res = 0;
for(auto n: nums) mp[n]++;
if(k==0) {
for(auto &x : mp) {
res += (x.second>1);
}
return res;
}
for(auto &x : mp) {
if(mp.count(x.first+k)) res++;
}
return res;
}
int findPairs(vector<int>& nums, int k) {
if(k<0) return 0;
unordered_map<int,int> mp;
int res = 0;
for(auto n: nums) mp[n]++;
if(k==0) {
for(auto &x : mp) {
res += (x.second>1);
}
return res;
}
for(auto &x : mp) {
if(mp.count(x.first+k)) res++;
}
return res;
}
Sunday, September 17, 2017
677. Map Sum Pairs
https://leetcode.com/problems/map-sum-pairs/description/
Implement a MapSum class with
insert
, and sum
methods.
For the method
insert
, you'll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one.
For the method
class MapSum {sum
, you'll be given a string representing the prefix, and you need to return the sum of all the pairs' value whose key starts with the prefix.unordered_map<string,int> mp;
public:
/** Initialize your data structure here. */
MapSum() {
}
void insert(string key, int val) {
mp[key] = val;
}
int sum(string prefix) {
int s = 0;
for(auto & x: mp) {
if(x.first.size()>=prefix.size()) {
int i;
for(i=0; i<prefix.size(); i++) {
if(x.first[i]!=prefix[i]) break;
}
if(i==prefix.size()) s += x.second;
}
}
return s;
}
};
680. Valid Palindrome II
https://leetcode.com/problems/valid-palindrome-ii/description/
Given a non-empty string
bool valid(string& s, int i, int j, int del) {
if(del == 2) return false;
if(i>=j) return true;
if(s[i]!=s[j])
return valid(s, i+1, j, del+1) || valid(s, i, j-1, del+1);
else return valid(s, i+1, j-1, del);
}
bool validPalindrome(string s) {
return valid(s, 0, s.size()-1, 0);
}
Given a non-empty string
s
, you may delete at most one character. Judge whether you can make it a palindrome.bool valid(string& s, int i, int j, int del) {
if(del == 2) return false;
if(i>=j) return true;
if(s[i]!=s[j])
return valid(s, i+1, j, del+1) || valid(s, i, j-1, del+1);
else return valid(s, i+1, j-1, del);
}
bool validPalindrome(string s) {
return valid(s, 0, s.size()-1, 0);
}
679. 24 Game
https://leetcode.com/problems/24-game/description/
You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through
Solution 1: Recursion.
vector<double> products(vector<int>& n, int L, int R) {
if(L == R) return {(double)n[L]};
vector<double> res;
for(int i=L; i<R; i++) {
vector<double> resl = products(n, L, i);
vector<double> resr = products(n, i+1, R);
for(auto l: resl) {
for(auto r: resr) {
res.push_back(l+r);
res.push_back(l-r);
res.push_back(l*r);
if(abs(r)>1e-8)
res.push_back(l/r);
}
}
}
return res;
}
bool judgePoint24(vector<int>& nums) {
sort(nums.begin(), nums.end());
do {
vector<double> res = products(nums, 0, nums.size()-1);
for(auto f: res) {
if(abs(f-24.0)<1e-6) return true;
}
} while(next_permutation(nums.begin(), nums.end()));
return false;
}
You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through
*
, /
, +
, -
, (
, )
to get the value of 24.Solution 1: Recursion.
vector<double> products(vector<int>& n, int L, int R) {
if(L == R) return {(double)n[L]};
vector<double> res;
for(int i=L; i<R; i++) {
vector<double> resl = products(n, L, i);
vector<double> resr = products(n, i+1, R);
for(auto l: resl) {
for(auto r: resr) {
res.push_back(l+r);
res.push_back(l-r);
res.push_back(l*r);
if(abs(r)>1e-8)
res.push_back(l/r);
}
}
}
return res;
}
bool judgePoint24(vector<int>& nums) {
sort(nums.begin(), nums.end());
do {
vector<double> res = products(nums, 0, nums.size()-1);
for(auto f: res) {
if(abs(f-24.0)<1e-6) return true;
}
} while(next_permutation(nums.begin(), nums.end()));
return false;
}
Saturday, September 16, 2017
678. Valid Parenthesis String
Solution 1. Use stacks. Storing the index of each char.
bool checkValidString(string s) {
stack<int> st;
stack<int> blk;
for(int i=0; i<s.size(); i++) {
char c = s[i];
if(c == '(') st.push(i);
else if(c == '*') blk.push(i);
else {
if(st.empty() && blk.empty()) return false;
if(!st.empty()) st.pop();
else blk.pop();
}
}
if(st.size()>blk.size()) return false;
while(!st.empty() && !blk.empty()) {
if(blk.top()<st.top()) return false;
st.pop();
blk.pop();
}
return st.empty();
}
Solution 2. Counting the remaining '(' at each step.
bool check(string& s, int i=0, int cnt=0) {
if(cnt < 0) return false;
if(i==s.size()) return cnt == 0;
if(s[i] == '(') return check(s, i+1, cnt+1);
else if(s[i] == ')') return check(s, i+1, cnt-1);
else return check(s, i+1, cnt)
|| check(s, i+1, cnt+1)
|| check(s, i+1, cnt-1);
}
bool checkValidString(string s) {
return check(s);
}
bool checkValidString(string s) {
stack<int> st;
stack<int> blk;
for(int i=0; i<s.size(); i++) {
char c = s[i];
if(c == '(') st.push(i);
else if(c == '*') blk.push(i);
else {
if(st.empty() && blk.empty()) return false;
if(!st.empty()) st.pop();
else blk.pop();
}
}
if(st.size()>blk.size()) return false;
while(!st.empty() && !blk.empty()) {
if(blk.top()<st.top()) return false;
st.pop();
blk.pop();
}
return st.empty();
}
Solution 2. Counting the remaining '(' at each step.
bool check(string& s, int i=0, int cnt=0) {
if(cnt < 0) return false;
if(i==s.size()) return cnt == 0;
if(s[i] == '(') return check(s, i+1, cnt+1);
else if(s[i] == ')') return check(s, i+1, cnt-1);
else return check(s, i+1, cnt)
|| check(s, i+1, cnt+1)
|| check(s, i+1, cnt-1);
}
bool checkValidString(string s) {
return check(s);
}
Friday, September 15, 2017
28. Implement strStr()
https://leetcode.com/problems/implement-strstr/description/
Solution. KMP search.
vector<int> calcLPS(const string& pat) {
vector<int> lps(pat.size(), 0);
int len = 0;
lps[0] = 0;
int i = 1;
while(i<pat.size()) {
if(pat[len] == pat[i]) {
len++;
lps[i++] = len;
}
else {
if(len != 0)
len = lps[len-1];
else
lps[i++] = 0;
}
}
return lps;
}
int strStr(string haystack, string needle) {
if(needle.size() == 0) return 0;
if(haystack.size() < needle.size()) return -1;
vector<int> lps = calcLPS(needle);
int i = 0;
int j = 0;
while(i<haystack.size()) {
if(haystack[i] == needle[j]) {
i++;
j++;
}
if(j == needle.size()) return i-j;
else if(i<haystack.size() && haystack[i] != needle[j]) {
if(j != 0) j = lps[j-1];
else i++;
}
}
return -1;
}
Solution. KMP search.
vector<int> calcLPS(const string& pat) {
vector<int> lps(pat.size(), 0);
int len = 0;
lps[0] = 0;
int i = 1;
while(i<pat.size()) {
if(pat[len] == pat[i]) {
len++;
lps[i++] = len;
}
else {
if(len != 0)
len = lps[len-1];
else
lps[i++] = 0;
}
}
return lps;
}
int strStr(string haystack, string needle) {
if(needle.size() == 0) return 0;
if(haystack.size() < needle.size()) return -1;
vector<int> lps = calcLPS(needle);
int i = 0;
int j = 0;
while(i<haystack.size()) {
if(haystack[i] == needle[j]) {
i++;
j++;
}
if(j == needle.size()) return i-j;
else if(i<haystack.size() && haystack[i] != needle[j]) {
if(j != 0) j = lps[j-1];
else i++;
}
}
return -1;
}
197. Rising Temperature
https://leetcode.com/problems/rising-temperature/description/
select w1.Id
from Weather as w1, Weather as w2
where TO_DAYS(w1.DATE) = TO_DAYS(w2.DATE) + 1
and W1.Temperature > W2.Temperature;
or,
select w1.Id
from Weather as w1, Weather as w2
where DATEDIFF(w1.DATE,w2.DATE) = 1
and W1.Temperature > W2.Temperature;
select w1.Id
from Weather as w1, Weather as w2
where TO_DAYS(w1.DATE) = TO_DAYS(w2.DATE) + 1
and W1.Temperature > W2.Temperature;
or,
select w1.Id
from Weather as w1, Weather as w2
where DATEDIFF(w1.DATE,w2.DATE) = 1
and W1.Temperature > W2.Temperature;
155. Min Stack
https://leetcode.com/problems/min-stack/description/
Solution 1. One stack
class MinStack {
stack<int> dst;
int mi = INT_MAX;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
if(x <= mi) {
dst.push(mi);
mi = x;
}
dst.push(x);
}
void pop() {
if(dst.top() == mi) {
dst.pop();
mi = dst.top();
}
dst.pop();
}
int top() {
return dst.top();
}
int getMin() {
return mi;
}
};
or, push the min every time pushing a new element.
class MinStack {
stack<int> dst;
int mi = INT_MAX;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
dst.push(mi);
if(x <= mi) mi = x;
dst.push(x);
}
void pop() {
dst.pop();
mi = dst.top();
dst.pop();
}
int top() {
return dst.top();
}
int getMin() {
return mi;
}
Solution 2. Two stacks.
class MinStack {
stack<int> dst;
stack<int> mst;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
int mi;
if(dst.empty()) mi = x;
else mi = min(mst.top(), x);
mst.push(mi);
dst.push(x);
}
void pop() {
dst.pop();
mst.pop();
}
int top() {
return dst.top();
}
int getMin() {
return mst.top();
}
};
Solution 1. One stack
class MinStack {
stack<int> dst;
int mi = INT_MAX;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
if(x <= mi) {
dst.push(mi);
mi = x;
}
dst.push(x);
}
void pop() {
if(dst.top() == mi) {
dst.pop();
mi = dst.top();
}
dst.pop();
}
int top() {
return dst.top();
}
int getMin() {
return mi;
}
};
or, push the min every time pushing a new element.
class MinStack {
stack<int> dst;
int mi = INT_MAX;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
dst.push(mi);
if(x <= mi) mi = x;
dst.push(x);
}
void pop() {
dst.pop();
mi = dst.top();
dst.pop();
}
int top() {
return dst.top();
}
int getMin() {
return mi;
}
Solution 2. Two stacks.
class MinStack {
stack<int> dst;
stack<int> mst;
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
int mi;
if(dst.empty()) mi = x;
else mi = min(mst.top(), x);
mst.push(mi);
dst.push(x);
}
void pop() {
dst.pop();
mst.pop();
}
int top() {
return dst.top();
}
int getMin() {
return mst.top();
}
};
581. Shortest Unsorted Continuous Subarray
https://leetcode.com/problems/shortest-unsorted-continuous-subarray/description/
int findUnsortedSubarray(vector<int>& nums) {
nums.insert(nums.begin(), INT_MIN);
nums.push_back(INT_MAX);
int l = 0, h = nums.size() - 1;
for(int i=1; i<nums.size()-1; i++ ) {
if(nums[i]<nums[l]) {
while(nums[i]<nums[l]) l--;
}
else if(l == i-1) l++;
}
for(int i=nums.size()-2; i>=0; i-- ) {
if(nums[i]>nums[h]) {
while(nums[i]>nums[h]) h++;
}
else if(h == i+1) h--;
}
return max(h-l-1, 0);
}
int findUnsortedSubarray(vector<int>& nums) {
nums.insert(nums.begin(), INT_MIN);
nums.push_back(INT_MAX);
int l = 0, h = nums.size() - 1;
for(int i=1; i<nums.size()-1; i++ ) {
if(nums[i]<nums[l]) {
while(nums[i]<nums[l]) l--;
}
else if(l == i-1) l++;
}
for(int i=nums.size()-2; i>=0; i-- ) {
if(nums[i]>nums[h]) {
while(nums[i]>nums[h]) h++;
}
else if(h == i+1) h--;
}
return max(h-l-1, 0);
}
190. Reverse Bits
https://leetcode.com/problems/reverse-bits/description/
uint32_t reverseBits(uint32_t n) {
int res = 0, f = 1;
for(int i=0; i<32; i++, n >>= 1) {
res <<= 1;
res |= (n & 1);
}
return res;
}
uint32_t reverseBits(uint32_t n) {
int res = 0, f = 1;
for(int i=0; i<32; i++, n >>= 1) {
res <<= 1;
res |= (n & 1);
}
return res;
}
Thursday, September 14, 2017
475. Heaters
https://leetcode.com/problems/heaters/description/
int findRadius(vector<int>& houses, vector<int>& heaters) {
sort(houses.begin(), houses.end());
sort(heaters.begin(), heaters.end());
int maxRg = 0, j = 0;
for(int i=0; i<houses.size(); i++) {
int h, minh = abs(heaters[j] - houses[i]);
while(j+1<heaters.size()) {
h = abs(heaters[j+1] - houses[i]);
if(h<=minh) {
minh = min(minh, h);
j++;
}
else {
break;
}
}
maxRg = max(maxRg, minh);
}
return maxRg;
}
int findRadius(vector<int>& houses, vector<int>& heaters) {
sort(houses.begin(), houses.end());
sort(heaters.begin(), heaters.end());
int maxRg = 0, j = 0;
for(int i=0; i<houses.size(); i++) {
int h, minh = abs(heaters[j] - houses[i]);
while(j+1<heaters.size()) {
h = abs(heaters[j+1] - houses[i]);
if(h<=minh) {
minh = min(minh, h);
j++;
}
else {
break;
}
}
maxRg = max(maxRg, minh);
}
return maxRg;
}
303. Range Sum Query - Immutable
https://leetcode.com/problems/range-sum-query-immutable/description/
Solution 1. Because:
You may assume that the array does not change.
There are many calls to sumRange function.
It is better to calculate sum when initialize the object.
class NumArray {
vector<int> sm;
public:
NumArray(vector<int> nums) {
sm.resize(nums.size()+1, 0);
for(int i=0; i<nums.size(); i++)
sm[i+1] = sm[i] + nums[i];
}
int sumRange(int i, int j) {
return sm[j+1] - sm[i];
}
};
Solution 2. do not calculate sum at initialization. Much slower.
class NumArray {
vector<int> n;
public:
NumArray(vector<int> nums) {
n = nums;
}
int sumRange(int i, int j) {
int s = 0;
for(int k=i; k<=j; k++)
s += n[k];
return s;
}
};
Solution 1. Because:
You may assume that the array does not change.
There are many calls to sumRange function.
It is better to calculate sum when initialize the object.
class NumArray {
vector<int> sm;
public:
NumArray(vector<int> nums) {
sm.resize(nums.size()+1, 0);
for(int i=0; i<nums.size(); i++)
sm[i+1] = sm[i] + nums[i];
}
int sumRange(int i, int j) {
return sm[j+1] - sm[i];
}
};
Solution 2. do not calculate sum at initialization. Much slower.
class NumArray {
vector<int> n;
public:
NumArray(vector<int> nums) {
n = nums;
}
int sumRange(int i, int j) {
int s = 0;
for(int k=i; k<=j; k++)
s += n[k];
return s;
}
};
605. Can Place Flowers
https://leetcode.com/problems/can-place-flowers/description/
Solution 1. add 0 to both side for convenience.
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
if(n == 0) return true;
if(flowerbed.size() == 0) return false;
flowerbed.insert(flowerbed.begin(),0);
flowerbed.push_back(0);
for(int i=1; i<flowerbed.size()-1; i++) {
if(flowerbed[i-1] + flowerbed[i] + flowerbed[i+1] == 0) {
i++;
n--;
}
}
return n<=0;
}
Solution 2.
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
if(n == 0) return true;
if(flowerbed.size() == 0) return false;
int z = flowerbed[0] ? 0 : 2, res = 0; // a 0 at beginning counted as 2
for(int i=1; i<flowerbed.size(); i++) {
if(flowerbed[i] == 1 && flowerbed[i-1] == 0) {
res += (z-1)/2;
z = 0;
if(res>=n) return true;
}
else if(flowerbed[i] == 0 && flowerbed[i-1] == 1) {
z = 1;
}
else if(flowerbed[i] == 0) z++;
else continue;
}
res += z/2;
if(res>=n) return true;
return false;
}
Solution 1. add 0 to both side for convenience.
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
if(n == 0) return true;
if(flowerbed.size() == 0) return false;
flowerbed.insert(flowerbed.begin(),0);
flowerbed.push_back(0);
for(int i=1; i<flowerbed.size()-1; i++) {
if(flowerbed[i-1] + flowerbed[i] + flowerbed[i+1] == 0) {
i++;
n--;
}
}
return n<=0;
}
Solution 2.
bool canPlaceFlowers(vector<int>& flowerbed, int n) {
if(n == 0) return true;
if(flowerbed.size() == 0) return false;
int z = flowerbed[0] ? 0 : 2, res = 0; // a 0 at beginning counted as 2
for(int i=1; i<flowerbed.size(); i++) {
if(flowerbed[i] == 1 && flowerbed[i-1] == 0) {
res += (z-1)/2;
z = 0;
if(res>=n) return true;
}
else if(flowerbed[i] == 0 && flowerbed[i-1] == 1) {
z = 1;
}
else if(flowerbed[i] == 0) z++;
else continue;
}
res += z/2;
if(res>=n) return true;
return false;
}
400. Nth Digit
https://leetcode.com/problems/nth-digit/description/
int findNthDigit(int n) {
vector<int> sd(9,0);
int d;
for(d=1; d<9; d++) {
// d is the length (digits of a single number) of a number
// sd is the total digits for length from 1 to d
sd[d] = d*pow(10, d) - (pow(10,d)-1)/9;
if(sd[d]>=n) break;
}
// the length of number prior to the current length
int d1 = d-1;
// total digits for length d is n - total digits for length from 1 to d-1
n -= sd[d1];
// the number is i-th of numbers with length d
int i = (n-1)/d;
// the first number of length d is
int a = pow(10, d1);
// what is the number
a += i;
// the digit is the i-th digit of the number a
i = n - i*d;
// return the digit
return (a/(int)(pow(10,d-i))) % 10;
}
int findNthDigit(int n) {
vector<int> sd(9,0);
int d;
for(d=1; d<9; d++) {
// d is the length (digits of a single number) of a number
// sd is the total digits for length from 1 to d
sd[d] = d*pow(10, d) - (pow(10,d)-1)/9;
if(sd[d]>=n) break;
}
// the length of number prior to the current length
int d1 = d-1;
// total digits for length d is n - total digits for length from 1 to d-1
n -= sd[d1];
// the number is i-th of numbers with length d
int i = (n-1)/d;
// the first number of length d is
int a = pow(10, d1);
// what is the number
a += i;
// the digit is the i-th digit of the number a
i = n - i*d;
// return the digit
return (a/(int)(pow(10,d-i))) % 10;
}
160. Intersection of Two Linked Lists
https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/
Solution 1.
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA || !headB) return nullptr;
ListNode* p = headA, *q = headB;
while(p != q) {
p = p? p->next : headB;
q = q? q->next : headA;
}
return p;
}
Solution 2. Counting the length of the lists.
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA || !headB) return nullptr;
ListNode* p, *q;
int na = 0, nb = 0, nd = 0;
p = headA;
while(p) {
na++;
p = p->next;
}
p = headB;
while(p) {
nb++;
p = p->next;
}
if(na>nb) {
p = headA;
q = headB;
}
else {
p = headB;
q = headA;
}
nd = abs(na - nb);
while(nd>0) {
p = p->next;
nd--;
}
while(p != q) {
p = p->next;
q = q->next;
}
return p;
}
Solution 1.
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA || !headB) return nullptr;
ListNode* p = headA, *q = headB;
while(p != q) {
p = p? p->next : headB;
q = q? q->next : headA;
}
return p;
}
Solution 2. Counting the length of the lists.
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(!headA || !headB) return nullptr;
ListNode* p, *q;
int na = 0, nb = 0, nd = 0;
p = headA;
while(p) {
na++;
p = p->next;
}
p = headB;
while(p) {
nb++;
p = p->next;
}
if(na>nb) {
p = headA;
q = headB;
}
else {
p = headB;
q = headA;
}
nd = abs(na - nb);
while(nd>0) {
p = p->next;
nd--;
}
while(p != q) {
p = p->next;
q = q->next;
}
return p;
}
Wednesday, September 13, 2017
14. Longest Common Prefix
https://leetcode.com/problems/longest-common-prefix/description/
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0 || strs[0].size() == 0) return "";
for(int j=0; j<strs[0].size(); j++) {
for(int i=1; i<strs.size(); i++) {
if(j>=strs[i].size() || strs[0][j] != strs[i][j]) {
return strs[0].substr(0,j);
}
}
}
return strs[0];
}
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0 || strs[0].size() == 0) return "";
for(int j=0; j<strs[0].size(); j++) {
for(int i=1; i<strs.size(); i++) {
if(j>=strs[i].size() || strs[0][j] != strs[i][j]) {
return strs[0].substr(0,j);
}
}
}
return strs[0];
}
58. Length of Last Word
https://leetcode.com/problems/length-of-last-word/description/
int lengthOfLastWord(string s) {
if(s.size() == 0) return 0;
int i = s.size()-1;
while(i>=0 && s[i] == ' ') i--;
if(i == -1) return 0;
int j;
for(j=i; j>=0; j--) {
if(s[j] == ' ') break;
}
return i-j;
}
int lengthOfLastWord(string s) {
if(s.size() == 0) return 0;
int i = s.size()-1;
while(i>=0 && s[i] == ' ') i--;
if(i == -1) return 0;
int j;
for(j=i; j>=0; j--) {
if(s[j] == ' ') break;
}
return i-j;
}
633. Sum of Square Numbers
https://leetcode.com/problems/sum-of-square-numbers/description/
bool judgeSquareSum(int c) {
int a = sqrt((double) c / 2.0);
int b = a;
int c2 = sqrt(c);
while(a>=0 && b<=c2) {
int s = a*a + b*b;
if(s<c) b++;
else if(s>c) a--;
else return true;
}
return false;
}
bool judgeSquareSum(int c) {
int a = sqrt((double) c / 2.0);
int b = a;
int c2 = sqrt(c);
while(a>=0 && b<=c2) {
int s = a*a + b*b;
if(s<c) b++;
else if(s>c) a--;
else return true;
}
return false;
}
88. Merge Sorted Array
https://leetcode.com/problems/merge-sorted-array/description/
Merge from high index.
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums2.size() == 0) return;
for(int i=m-1, j=n-1, k=m+n-1; k>=0; k--) {
if(i<0) {
nums1[k] = nums2[j--];
continue;
}
if(j<0) return;
if(nums1[i]<=nums2[j]) nums1[k] = nums2[j--];
else nums1[k] = nums1[i--];
}
}
Merge from high index.
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
if(nums2.size() == 0) return;
for(int i=m-1, j=n-1, k=m+n-1; k>=0; k--) {
if(i<0) {
nums1[k] = nums2[j--];
continue;
}
if(j<0) return;
if(nums1[i]<=nums2[j]) nums1[k] = nums2[j--];
else nums1[k] = nums1[i--];
}
}
219. Contains Duplicate II
https://leetcode.com/problems/contains-duplicate-ii/description/
Solution 1. Use map to store the index for each distinct number.
bool containsNearbyDuplicate(vector<int>& nums, int k) {
if(nums.size()<2) return false;
unordered_map<int, int> mp;
for(int i=0; i<nums.size(); i++) {
if(mp.count(nums[i]))
if(i - mp[nums[i]]<=k) return true;
mp[nums[i]] = i;
}
return false;
}
Solution 2. Use unordered_set to maintain a set containing nums[i-k,...,i-1].
bool containsNearbyDuplicate(vector<int>& nums, int k) {
if(nums.size()<2 || k<=0) return false;
unordered_set<int> st;
for(int i=0; i<nums.size(); i++) {
if(st.count(nums[i]))
return true;
else {
if(i-k>=0) st.erase(nums[i-k]);
st.insert(nums[i]);
}
}
return false;
}
Solution 1. Use map to store the index for each distinct number.
bool containsNearbyDuplicate(vector<int>& nums, int k) {
if(nums.size()<2) return false;
unordered_map<int, int> mp;
for(int i=0; i<nums.size(); i++) {
if(mp.count(nums[i]))
if(i - mp[nums[i]]<=k) return true;
mp[nums[i]] = i;
}
return false;
}
Solution 2. Use unordered_set to maintain a set containing nums[i-k,...,i-1].
bool containsNearbyDuplicate(vector<int>& nums, int k) {
if(nums.size()<2 || k<=0) return false;
unordered_set<int> st;
for(int i=0; i<nums.size(); i++) {
if(st.count(nums[i]))
return true;
else {
if(i-k>=0) st.erase(nums[i-k]);
st.insert(nums[i]);
}
}
return false;
}
Tuesday, September 12, 2017
203. Remove Linked List Elements
https://leetcode.com/problems/remove-linked-list-elements/description/
Solution 0. Iteration 1. use pointer to a pointer.
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
ListNode** pn = &head;
while(*pn) {
if((*pn)->val == val) {
*pn = (*pn)->next;
}
else {
pn = &(*pn)->next;
}
}
return head;
}
Solution 1. Recursion 0
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
head->next = removeElements(head->next, val);
ListNode* node = head;
if(head->val == val) {
head = head->next;
}
return head;
}
Solution 1.1 Recursion 1
void remove(ListNode*& node, int val) {
if(!node) return;
if(node->val == val) {
node = node->next;
remove(node, val);
}
else remove(node->next, val);
}
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
remove(head, val);
return head;
}
Solution 2. Iteration 2
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
ListNode* node = head, *pre = head;
while(node) {
if(node->val == val) {
if(node == head) {
head = head->next;
node = head;
pre = head;
}
else {
pre->next = node->next;
node = pre->next;
}
}
else {
pre = node;
node = node->next;
}
}
return head;
}
Solution 0. Iteration 1. use pointer to a pointer.
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
ListNode** pn = &head;
while(*pn) {
if((*pn)->val == val) {
*pn = (*pn)->next;
}
else {
pn = &(*pn)->next;
}
}
return head;
}
Solution 1. Recursion 0
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
head->next = removeElements(head->next, val);
ListNode* node = head;
if(head->val == val) {
head = head->next;
}
return head;
}
Solution 1.1 Recursion 1
void remove(ListNode*& node, int val) {
if(!node) return;
if(node->val == val) {
node = node->next;
remove(node, val);
}
else remove(node->next, val);
}
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
remove(head, val);
return head;
}
Solution 2. Iteration 2
ListNode* removeElements(ListNode* head, int val) {
if(!head) return head;
ListNode* node = head, *pre = head;
while(node) {
if(node->val == val) {
if(node == head) {
head = head->next;
node = head;
pre = head;
}
else {
pre->next = node->next;
node = pre->next;
}
}
else {
pre = node;
node = node->next;
}
}
return head;
}
67. Add Binary
https://leetcode.com/problems/add-binary/description/
string addBinary(string a, string b) {
if(a.size()<b.size()) return addBinary(b, a);
int c = 0;
int j = b.size()-1, i = a.size()-1;
for(;i>=0 && (c||j>=0); i--,j--,c/=2) {
c += a[i] - '0' + (j>=0? b[j] - '0':0);
a[i] = c%2 + '0';
}
return (c? "1":"") + a;
}
string addBinary(string a, string b) {
if(a.size()<b.size()) return addBinary(b, a);
int c = 0;
int j = b.size()-1, i = a.size()-1;
for(;i>=0 && (c||j>=0); i--,j--,c/=2) {
c += a[i] - '0' + (j>=0? b[j] - '0':0);
a[i] = c%2 + '0';
}
return (c? "1":"") + a;
}
183. Customers Who Never Order
https://leetcode.com/problems/customers-who-never-order/description/
select C.Name as Customers
from Customers as C
where C.Id not in (select Orders.CustomerId from Orders);
select C.Name as Customers
from Customers as C
left join Orders on C.Id = Orders.CustomerId
where Orders.CustomerId is null
select C.Name as Customers
from Customers as C
where not exists (select CustomerId from Orders where C.Id = Orders.CustomerId);
select C.Name as Customers
from Customers as C
where C.Id not in (select Orders.CustomerId from Orders);
select C.Name as Customers
from Customers as C
left join Orders on C.Id = Orders.CustomerId
where Orders.CustomerId is null
select C.Name as Customers
from Customers as C
where not exists (select CustomerId from Orders where C.Id = Orders.CustomerId);
234. Palindrome Linked List
https://leetcode.com/problems/palindrome-linked-list/description/
Solution 1. Use a recursive call to check the values. The call stack acts as a stack for the node values, which access the node values backwardly. At the same time, use a pointer p to access the node values forwardly. O(n) in space.
bool isPalindrome(ListNode* head) {
ListNode* p = head;
return check(head, p);
}
bool check(ListNode* node, ListNode*& p) {
if(!node) return true;
bool isNext = check(node->next,p) && (node->val == p->val);
p = p->next;
return isNext;
}
Solution 2. O(1) space?
bool isPalindrome(ListNode* head) {
if(!head || !head->next) return true;
ListNode* slow = head, * fast = head, *p;
while(fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
fast = reverseList(slow->next);
slow->next = fast;
p = head;
while(fast) {
if(p->val != fast->val) return false;
p = p->next;
fast = fast->next;
}
slow->next = reverseList(slow->next);
return true;
}
ListNode* reverseList(ListNode* head){
ListNode* hd = nullptr, * next;
while(head) {
next = head->next;
head->next = hd;
hd = head;
head = next;
}
return hd;
}
Solution 1. Use a recursive call to check the values. The call stack acts as a stack for the node values, which access the node values backwardly. At the same time, use a pointer p to access the node values forwardly. O(n) in space.
bool isPalindrome(ListNode* head) {
ListNode* p = head;
return check(head, p);
}
bool check(ListNode* node, ListNode*& p) {
if(!node) return true;
bool isNext = check(node->next,p) && (node->val == p->val);
p = p->next;
return isNext;
}
Solution 2. O(1) space?
bool isPalindrome(ListNode* head) {
if(!head || !head->next) return true;
ListNode* slow = head, * fast = head, *p;
while(fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
fast = reverseList(slow->next);
slow->next = fast;
p = head;
while(fast) {
if(p->val != fast->val) return false;
p = p->next;
fast = fast->next;
}
slow->next = reverseList(slow->next);
return true;
}
ListNode* reverseList(ListNode* head){
ListNode* hd = nullptr, * next;
while(head) {
next = head->next;
head->next = hd;
hd = head;
head = next;
}
return hd;
}
195. Tenth Line
https://leetcode.com/problems/tenth-line/description/
#
cnt=0
while read line && [ $cnt -le 10 ];
do
let 'cnt = cnt + 1'
if [ $cnt -eq 10 ]; then
echo $line
exit 0
fi
done < file.txt
#use AWK
awk '{if(NR==10) print $0}' file.txt
awk 'FNR == 10 {print }' file.txt
awk 'NR == 10' file.txt
#use sed
sed -n 10p file.txt
#use tail
tail -n+10 file.txt|head -1
#
cnt=0
while read line && [ $cnt -le 10 ];
do
let 'cnt = cnt + 1'
if [ $cnt -eq 10 ]; then
echo $line
exit 0
fi
done < file.txt
#use AWK
awk '{if(NR==10) print $0}' file.txt
awk 'FNR == 10 {print }' file.txt
awk 'NR == 10' file.txt
#use sed
sed -n 10p file.txt
#use tail
tail -n+10 file.txt|head -1
225. Implement Stack using Queues
https://leetcode.com/problems/implement-stack-using-queues/description/
class MyStack {
queue<int> q;
public:
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
q.push(x);
for(int i=0; i<q.size()-1;i++) {
q.push(q.front());
q.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int x = q.front();
q.pop();
return x;
}
/** Get the top element. */
int top() {
return q.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q.empty();
}
};
class MyStack {
queue<int> q;
public:
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
q.push(x);
for(int i=0; i<q.size()-1;i++) {
q.push(q.front());
q.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int x = q.front();
q.pop();
return x;
}
/** Get the top element. */
int top() {
return q.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return q.empty();
}
};
Subscribe to:
Posts (Atom)