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][n]),minimumTotal(triangle,m+1,n+1,result+triangle[m][n]));
}
};
接着试了试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];
}
};