您的位置:首页 > 其它

【LeetCode111-120】很多道二叉树的问题(左右顺序很重要),一道hard DP题,两道杨辉三角以及一道DP三角

2017-04-24 16:20 453 查看

111.返回二叉树最短长度【easy】

例如【1,2】的长度为2!!也就是node到最近的叶子的长度

class Solution {
public:
int minDepth(TreeNode* root) {
if(!root)return 0;
if(!root->left)return 1+minDepth(root->right);
if(!root->right)return 1+minDepth(root->left);
return min(minDepth(root->left),minDepth(root->right))+1;
}
};




112.判断从根到叶有没有何为sum的一条路径

注意【】,0返回的是false....所有对于空要单独判断下

class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(!root)return false;
if(!root->left&&!root->right){if(sum==root->val)return true;return false;}
if(!root->left)return hasPathSum(root->right,sum-root->val);
if(!root->right)return hasPathSum(root->left,sum-root->val);
if(hasPathSum(root->right,sum-root->val))return true;
if(hasPathSum(root->left,sum-root->val))return true;
return false;
}
};


别人的思路一样但简洁了很多的方法:

bool hasPathSum(TreeNode *root, int sum) {
if (root == NULL) return false;
if (root->val == sum && root->left ==  NULL && root->right == NULL) return true;
return hasPathSum(root->left, sum-root->val) || hasPathSum(root->right, sum-root->val);
}


113.输出所有根到叶和为sum的路径

在112基础上迭代一下……记得temp要pop...

class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>>result;
vector<int>temp;
help(result,temp,root,sum);
return result;
}
void help(vector<vector<int>>&result,vector<int>&temp,TreeNode* root,int sum){
if(!root)return;
temp.push_back(root->val);
if(!root->left&&!root->right&&root->val==sum){
result.push_back(temp);
}
if(root->left){help(result,temp,root->left,sum-root->val);temp.pop_back();}
if(root->right){help(result,temp,root->right,sum-root->val);temp.pop_back();}
return;
}
};


114.二叉树转化为单链表【medium】

Given a binary tree, flatten it to a linked list in-place.

For example,

Given
1
/ \
2   5
/ \   \
3   4   6


The flattened tree should look like:

1
\
2
\
3
\
4
\
5
\
6


root->left=nullptr;一定要加上!!!不然会报错double free....因为左侧和右侧都指向了同一个……

class Solution {
public:
void flatten(TreeNode* root) {
//
if(!root)return;
flatten(root->left);
TreeNode* temp=root->right;
root->right=root->left;
root->left=nullptr;//一定要加上!!不然报double free...
//  TreeNode* temp2=root;
while(root->right){
root=root->right;//并不一定要保证root指针一定要指向开头(检测机制还是很强大的)
}
root->right=temp;
flatten(root->right);
}

};




115.S删去几个字符转化为T的种数【hard】

Given a string S and a string T, count the number of distinct subsequences of T in S.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie,
"ACE"
is
a subsequence of
"ABCDE"
while
"AEC"
is
not).

Here is an example:

S =
"rabbbit"
, T =
"rabbit"


Return
3
.

DP问题

dp[i][j]代表t的前i+1位被s的前j+1位弄出来的个数

如果t[i]和s[j]相等,那么dp[i][j]=dp[i][j-1]+dp[i-1][j-1];

否则dp[i][j]=dp[i][j-1];

数学归纳法……也就是DP……

class Solution {
public:
int numDistinct(string s, string t) {
//试试DP
if(s.empty()&&t.size()>0)return 0;
if(t.empty())return 1;

vector<vector<int>>dp(t.size(), vector<int>(s.size(), 0));
//行数代表T,列数代表S
if (s[0] == t[0])dp[0][0] = 1;
for (int i = 1; i<s.size(); ++i) { if (s[i] == t[0])dp[0][i] = dp[0][i - 1] + 1; else dp[0][i] = dp[0][i - 1]; }
//列不用管了,都是0
for (int i = 1; i<t.size(); ++i) {
for (int j = 1; j<s.size(); ++j) {
if (t[i] == s[j]) {
dp[i][j] = dp[i][j-1] + dp[i - 1][j - 1];
}
else dp[i][j] = dp[i][j - 1];
}
}
return dp[t.size() - 1][s.size() - 1];
}
};


116.把二叉树同层的串起来【medium】

Given a binary tree
struct TreeLinkNode {
TreeLinkNode *left;
TreeLinkNode *right;
TreeLinkNode *next;
}


Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to
NULL
.

Initially, all next pointers are set to
NULL
.

Note:

You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,

Given the following perfect binary tree,

1
/  \
2    3
/ \  / \
4  5  6  7


After calling your function, the tree should look like:

1 -> NULL
/  \
2 -> 3 -> NULL
/ \  / \
4->5->6->7 -> NULL

击败了90%的人…

/**
* Definition for binary tree with next pointer.
* struct TreeLinkNode {
*  int val;
*  TreeLinkNode *left, *right, *next;
*  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
* };
*/
class Solution {
public:
void connect(TreeLinkNode *root) {
//迭代…可以用一个的尽量用一个,不然要花更多时间
if(!root||!root->left)return;//因为正好是完全二叉树……
root->left->next=root->right;
if(root->next)root->right->next=root->next->left;//这一行很关键…把两棵子树串起来了
connect(root->left);
connect(root->right);
return;
}
};


117.上一题加强版,任意二叉树同级串起来

Follow up for problem "Populating Next Right Pointers in Each Node".

What if the given tree could be any binary tree? Would your previous solution still work?

Note:

You may only use constant extra space.

For example,

Given the following binary tree,

1
/  \
2    3
/ \    \
4   5    7


After calling your function, the tree should look like:

1 -> NULL
/  \
2 -> 3 -> NULL
/ \    \
4-> 5 -> 7 -> NULL


这题调bug调了很久…………

最后发现应该先connect右边再左边,不然上一行还没遍历完,缺少next信息!!!

class Solution {
public:
void connect(TreeLinkNode *root) {
if (!root)return;
if (!root->left && !root->right)return;
if (root->left) {
if (root->right) {
root->left->next = root->right;
TreeLinkNode *temp = root;
while (temp->next) {
if (temp->next->left) { root->right->next = temp->next->left; break; }
else if (temp->next->right) { root->right->next = temp->next->right; break; }
temp = temp->next;
}
/*先右再左非常非常非常关键!!!不然下一行运行的时候缺少上方的next信息,先右边就没问题了……*/
connect(root->right);
connect(root->left);
}
else {
TreeLinkNode *temp = root;
while (temp->next) {
if (temp->next->left) { root->left->next = temp->next->left; break; }
else if (temp->next->right) { root->left->next = temp->next->right; break; }
temp = temp->next;
}
connect(root->left);
}
}
else if (root->right) {
TreeLinkNode *temp = root;
while (temp->next) {
if (temp->next->left) { root->right->next = temp->next->left; break; }
else if (temp->next->right) { root->right->next = temp->next->right; break; }
temp = temp->next;
}
connect(root->right);
}

return;
}
};


118.杨辉三角的实现(帕斯卡三角)

Given numRows, generate the first numRows of Pascal's triangle.

For example, given numRows = 5,

Return
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]


class Solution {
public:
vector<vector<int>> generate(int numRows) {
//杨辉三角,数字等于上一行俩相加
vector<vector<int>>result;
if(numRows==0)return result;
result.push_back({1});
for(int i=2;i<=numRows;++i)help(result,i);
return result;

}
void help(vector<vector<int>>&result,int n){
vector<int>temp(n,1);
for(int i=1;i<n-1;++i){
temp[i]=result.back()[i]+result.back()[i-1];
}
result.push_back(temp);
}
};




119.输出杨辉三角第k+1行

O(n),空间利用最低,击败了80%…

从{1}不断迭代到最终结果,空间利用率应该接近最高了

class Solution {
public:
vector<int> getRow(int k) {
vector<int>temp(1,1);
for(int i=2;i<=k+1;++i){
temp.push_back(1);
int help=1;
for(int j=1;j<i-1;++j){
temp[j]=temp[j]+help;
help=temp[j]-help;
}
}
return temp;
}
};


120.三角形vector里找到和最小的从上到下的路径

直观上第一感觉是迭代,果然42/43,代码如下:

class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
return minimumTotal(triangle,0,0,0);
}
int minimumTotal(vector<vector<int>>& triangle,int m,int n,int result){
if(m==triangle.size())return result;
return min(minimumTotal(triangle,m+1,n,result+triangle[m]
),minimumTotal(triangle,m+1,n+1,result+triangle[m]
));
}
};
接着试了试DP(题目里只允许用O(n)空间)

然后发现可以只用了O(1)空间

class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
for(int i=1;i<triangle.size();++i){
triangle[i][0]+=triangle[i-1][0];
for(int j=1;j<triangle[i-1].size();++j){
triangle[i][j]+=min(triangle[i-1][j],triangle[i-1][j-1]);
}
triangle[i].back()+=triangle[i-1].back();
}
int result=2147483647;
for(auto ii:triangle.back()){
result=min(ii,result);
}
return result;

}

};
继而看了下别人的方法,发现可以由下而上!!简直机智……

简洁了很多,而且计算量降低了…

class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
//再试试自下而上
for(int i=triangle.size()-2;i>=0;--i){
for(int j=0;j<triangle[i].size();++j){
triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]);
}
}
return triangle[0][0];
}

};


祝刷题愉快~~

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐