【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 treestruct 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]; } };
祝刷题愉快~~
相关文章推荐
- 【LeetCode81-90】三道链表,两道找最大面积的hard题,一道二叉树的hard题和一些找自信题……
- LeetCode Triangle 120 DP问题
- 每天一道LeetCode-----判断二叉树左右两边是否成镜像关系
- leetcode 213. House Robber II 入室抢劫 抢劫问题 + 一道经典的DP动态规划问题
- Leetcode--两道简单的二进制问题
- 获取二叉树的叶子数、高度以及左右子树的交换的C语言实现
- 简述P问题,NP问题,NPC问题以及NP Hard问题
- 2015年创业中遇到的技术问题:111-120
- 剑指offer 01-06解答思路以及代码(顺序数组找特定数字,替换空格字符,链表反转输出,重建二叉树,两个栈实现队列效果,旋转数组最小元素)
- LeetCode 107. Binary Tree Level Order Traversal II (二叉树阶层顺序遍历之二)
- leetCode 104. Maximum Depth of Binary Tree 二叉树问题
- 子集系列(一) 传统subset 问题,例 [LeetCode] Subset, Subset II, Bloomberg 的一道面试题
- 实现二叉树以及链表发现的问题
- ViewPager禁止滑动,设置页片间距,设置当前显示的页面,缓存个数,以及解决嵌套ViewPager左右滑动冲突问题
- MFC模式对话框与非模式对话框 消息处理顺序 与非模式对话框的焦点问题、显示、关闭以及交互问题
- 【LeetCode61-70】旋转链表,三道标准DP问题,正则表达式,word文字排版规则,
- LeetCode 刷题: 左右反转一个二叉树
- LeetCode 62/63/120/64 Unique PathsI/II Triangle/Min sum Path/Rectangle Area--DP
- 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
- leetcode 198. House Robber(DP问题)