Friday, January 31, 2014
[leetcode] Combination Sum
vector<vector<int> > findcombination(vector<int> valid, int target){
vector<vector<int> > res;
int len = valid.size();
if(len == 0) return res;
//discard all the values larger than target.
while(valid.back() > target){
valid.pop_back();
if(valid.empty()) return res;
}
int i = valid.size() - 1;
while( i >= 0 ){
int head = valid[i];
int cur = head;
valid.pop_back();
vector<int> headvec;
while(cur <= target){
headvec.push_back(head);
if(cur == target){
res.push_back(headvec);
break;
}
vector<vector<int> > tails = findcombination(valid, target - cur);
for(int j = 0; j < tails.size(); ++j){
for(int k = 0; k < headvec.size(); ++k){
tails[j].push_back(headvec[k]);
}
res.push_back(tails[j]);
}
cur+=head;
}
--i;
}
return res;
}
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
vector<vector<int> > res;
if(candidates.empty()) return res;
sort(candidates.begin(), candidates.end());
res = findcombination(candidates, target);
return res;
}
=========================================================
void dfs(int left, vector<int>& candidates, vector<int>& current, vector< vector<int> >& ret, int target) {
if (!target) {ret.push_back(current); return;}
for (int i = left; i < (int)candidates.size(); ++ i) {
if (candidates[i] > target) break;
current.push_back(candidates[i]);
dfs(i, candidates, current, ret, target - candidates[i]);
current.pop_back();
}
}
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
vector< vector<int> > ret;
vector<int> current;
sort(candidates.begin(), candidates.end());
dfs(0, candidates, current, ret, target);
return ret;
}
Thursday, January 30, 2014
[leetcode] Minimum Path Sum *
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
My Code:
int minPathSum(vector<vector<int> > &grid) {
if(grid.empty()) return 0;
int width = grid[0].size();
int height = grid.size();
int table[height][width];
table[0][0] = grid[0][0];
for(int i = 0; i < height; ++i){
for(int j = 0; j < width; ++j){
if(i == 0 && j != 0 )
table[0][j] = table[0][j-1]+grid[0][j];
else if(j == 0 && i != 0)
table[i][0] = table[i-1][0]+grid[i][0];
else if(i != 0 && j != 0){
table[i][j] = min(table[i-1][j], table[i][j-1]) + grid[i][j];
}
}
}
return table[height-1][width-1];
}
[leetcode] Path Sum II
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
For example:Given the below binary tree and
sum = 22, 5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
return
[ [5,4,11,2], [5,8,4,5] ]
My Code:
vector<vector<int> > pathSum(TreeNode *root, int sum) {
vector<vector<int> > res;
vector<int> path;
if(!root) return res;
if(!root->left && !root->right){
if(root->val == sum){
path.push_back(root->val);
res.push_back(path);
return res;
}else{
return res;
}
}else{
if(root->left){
vector<vector<int> > leftres = pathSum(root->left, sum - (root->val));
for(int i = 0; i < leftres.size(); ++i){
leftres[i].insert(leftres[i].begin(), root->val);
res.push_back(leftres[i]);
}
}
if(root->right){
vector<vector<int> > rightres = pathSum(root->right, sum - (root->val));
for(int i = 0; i < rightres.size(); ++i){
rightres[i].insert(rightres[i].begin(), root->val);
res.push_back(rightres[i]);
}
}
return res;
}
}
[leetcode] Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:Given the below binary tree and
sum = 22, 5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
return true, as there exist a root-to-leaf path
5->4->11->2 which sum is 22.
My Code:
bool hasPathSum(TreeNode *root, int sum) {
if(!root) return false;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
TreeNode* cur = q.front();
if(!cur->left && !cur->right){
if(cur->val == sum)
return true;
}
else{
if(cur->left){
cur->left->val = cur->val + cur->left->val;
q.push(cur->left);
}
if(cur->right){
cur->right->val = cur->val + cur->right->val;
q.push(cur->right);
}
}
q.pop();
}
return false;
}
[leetcode] Sum Root to Leaf Numbers
Given a binary tree containing digits from
0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path
1->2->3 which represents the number 123.
Find the total sum of all root-to-leaf numbers.
For example,
1 / \ 2 3
The root-to-leaf path
The root-to-leaf path
1->2 represents the number 12.The root-to-leaf path
1->3 represents the number 13.
Return the sum = 12 + 13 =
25.
My Code:
int sumNumbers(TreeNode *root) {
if(!root) return 0;
queue q;
q.push(root);
int sum = 0;
while(!q.empty()){
TreeNode* cur = q.front();
if(!cur->left && !cur->right){
sum = sum + cur->val;
}
else{
if(cur->left){
cur->left->val = cur->val*10 + cur->left->val;
q.push(cur->left);
}
if(cur->right){
cur->right->val = cur->val*10 + cur->right->val;
q.push(cur->right);
}
}
q.pop();
}
return sum;
}
[leetcode] Median of Two Sorted Arrays
There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Basic:
Definition of Median:
The median of a finite list of numbers can be found by arranging all the observations from lowest value to highest value and picking the middle one (e.g., the median of {3, 3, 5, 9, 11} is 5). If there is an even number of observations, then there is no single middle value; the median is then usually defined to be the mean of the two middle values (the median of {3, 5, 7, 9} is (5 + 7) / 2 = 6), which corresponds to interpreting the median as the fully trimmed mid-range.
Algorithm:
This problems seems to be easy, it can be done by O((n+m)log(m+n)) and O((m+n)). However, when it comes to O(log(m+n)), it becomes difficult. We can do this via "find kth largest in a sorted array" and do this separately on odd and even.
1. For odd, just find (m+n)/2 +1 th number. For eve, find (m+n)/2 th and find (m+n)/2+1 th and get the average of these two.
2. For findkth function, we should keep the smaller one as m always and then then it will balanced to be log(m+n).
My Code:
Basic:
Definition of Median:
The median of a finite list of numbers can be found by arranging all the observations from lowest value to highest value and picking the middle one (e.g., the median of {3, 3, 5, 9, 11} is 5). If there is an even number of observations, then there is no single middle value; the median is then usually defined to be the mean of the two middle values (the median of {3, 5, 7, 9} is (5 + 7) / 2 = 6), which corresponds to interpreting the median as the fully trimmed mid-range.
Algorithm:
This problems seems to be easy, it can be done by O((n+m)log(m+n)) and O((m+n)). However, when it comes to O(log(m+n)), it becomes difficult. We can do this via "find kth largest in a sorted array" and do this separately on odd and even.
1. For odd, just find (m+n)/2 +1 th number. For eve, find (m+n)/2 th and find (m+n)/2+1 th and get the average of these two.
2. For findkth function, we should keep the smaller one as m always and then then it will balanced to be log(m+n).
My Code:
Wednesday, January 29, 2014
[leetcode] Search in Rotated Sorted Array II
Follow up for "Search in Rotated Sorted Array":
What if duplicates are allowed?
What if duplicates are allowed?
Would this affect the run-time complexity? How and why?
Write a function to determine if a given target is in the array.
Algorithm:
The difference here is that how to handle when A[mid] == A[right]!
then we can not decide the pivot location when A[mid] == A[right]. My solution is that when this happens, just move right to left until A[mid] != A[right].
There may be better solutions, can update later.
My Code:
bool RS(int A[], int left, int right, int target){
if(right < left) return false;
if(left == right) {
if(A[left] == target) return true;
else return false;
}
int mid = (left+right)/2;
if(A[mid] == target) return true;
if(A[mid] == A[right]){
while(A[mid] == A[right] && right >= 0){
right--;
}
return RS(A, left, right, target);
}
else if(A[mid] < A[right]){
// rotated pivot on the left
if(target < A[mid]) return RS(A, left, mid-1, target);
else{
if(target > A[right]) return RS(A, left, mid-1, target);
else return RS(A, mid+1, right, target);
}
} else {
//rotated pivot on the right
if(target > A[mid]) return RS(A, mid+1, right, target);
else{
if(target > A[right]) return RS(A, left, mid-1, target);
else return RS(A, mid+1, right, target);
}
}
}
bool search(int A[], int n, int target) {
if(n <= 0) return false;
return RS(A, 0, n-1, target);
}
Subscribe to:
Posts (Atom)