您的位置:首页 > 其它

leetcode题解日练--2016.7.26

2016-07-27 01:36 453 查看
日练三题,冰冻三尺非一日之寒。

今日题目:

1、用先序遍历和中序遍历去建立树; | tag:树|数组|DFS

2、用中序遍历和后序遍历去建立树; |tag:树|数组|DFS

3、丑数II。 |tag:DP|堆|数学

今日摘录:

如果有天我们湮没在人潮之中,

庸碌一生,

那是因为我们没有努力要活得丰盛。

——黄碧云

105. Construct Binary Tree from Preorder and Inorder Traversal | Difficulty: Medium

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:

You may assume that duplicates do not exist in the tree.

tag:树|数组|DFS

题意:给一棵二叉树的前序和中序遍历,构建这课二叉树

思路:

1、递归去求解,首先,根据前序遍历能够找到树的根节点就是前序遍历的第一个元素。这个时候怎么找根节点的左节点和右节点呢?我们用根节点将这棵树划为左子树和右子树,我们需要递归去求解左子树的前序遍历,因为根据前序遍历能找到根节点,那么如果确定一棵树哪些部分是左子树,哪些部分是右子树呢?这就需要利用中序遍历了。中序遍历当前根节点,根节点的index左边是左子树,右边是右子树。看栗子:

原树:[1,2,3,4,5,6,7]

先序:[1,2,4,5,3,6,7]

中序:[4,2,5,1,6,3,7]

后序:[4,5,2,6,7,3,1]

首先找到根节点4,然后根节点的index=3,这个时候划分为左子树和右子树,左子树的先序遍历下标是[1,3],中序遍历下标是[0,2],右子树的先序遍历下标是[4,6],中序遍历下标是[4,6]。

自己去递归写几步就能看出规律来,

左子树先序遍历下标=[原来先序起始+1,index]

左子树中序遍历下标=[原来中序起始位置,index-1]

右子树先序遍历下标=[原来先序起始+(index-原来中序起始,这个值也就是index的相对偏移量)+1,原来先序终止位置]

右子树中序遍历下标=[index+1,原来中序终止位置]

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return dfs(0,0,preorder.size()-1,inorder.size()-1,preorder,inorder);
}
TreeNode* dfs(int preStart,int inStart,int preEnd,int inEnd,vector<int>&preorder,vector<int>&inorder)
{
if(preStart>preorder.size()-1 || inStart>inEnd)
{
return NULL;
}
TreeNode*root = new TreeNode (preorder[preStart]);
int index=0;
for(int i=inStart;i<=inEnd;i++)
{
if(inorder[i]==root->val)  {index = i;break;}
}
root->left = dfs(preStart+1,inStart,index,index-1,preorder,inorder);
root->right = dfs(preStart+index-inStart+1,index+1,preEnd,inEnd,preorder,inorder);
return root;
}
};


结果:36ms

update:2016.9.16,第二次刷代码,将代码形式写成与中序后序相同的形式

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
return dfs(0,0,preorder.size()-1,inorder.size()-1,preorder,inorder);
}
TreeNode* dfs(int preStart,int inStart,int preEnd,int inEnd,vector<int>&preorder,vector<int>&inorder)
{
if(preStart>preEnd||inStart>inEnd)
return NULL;
TreeNode* root = new TreeNode (preorder[preStart]);
int index = 0;
for(int i=inStart;i<=inEnd;i++)
{
if(inorder[i]==root->val) {index = i;break;}
}
root->left = dfs(preStart+1,inStart,preStart+index-inStart,index-1,preorder,inorder);
root->right = dfs(preStart+index-inStart+1,index+1,preEnd,inEnd,preorder,inorder);
return root;
}
};


结果:39ms

106. Construct Binary Tree from Inorder and Postorder Traversal | Difficulty: Medium

Given inorder and postorder traversal of a tree, construct the binary tree.

Note:

You may assume that duplicates do not exist in the tree.

tag:树|数组|DFS

题意:给定一个中序遍历一个后序遍历,去建造原来的树。

思路:

1、递归,与上题类似

/**
* Definition for a binary tree node.
* struct TreeNode {
*     int val;
*     TreeNode *left;
*     TreeNode *right;
*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
return dfs(0,0,postorder.size()-1,inorder.size()-1,postorder,inorder);
}
TreeNode* dfs(int postStart,int inStart,int postEnd,int inEnd,vector<int>&postorder,vector<int>&inorder)
{
if(postStart>postEnd||inStart>inEnd)
return NULL;
TreeNode* root = new TreeNode (postorder[postEnd]);
int index = 0;
for(int i=inStart;i<=inEnd;i++)
{
if(inorder[i]==root->val) {index = i;break;}
}
root->left = dfs(postStart,inStart,postStart+index-inStart-1,index-1,postorder,inorder);
root->right = dfs(postStart+index-inStart,index+1,postEnd-1,inEnd,postorder,inorder);
return root;
}
};


结果:40ms

264. Ugly Number II |Difficulty: Medium

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number.

tag:DP|堆|数学

相关题目:丑数 超级丑数

题意:找到第n个丑数,丑数的定义是

思路:

1、超级丑数的一种特例

class Solution {
public:
int nthUglyNumber(int n) {
vector<int> uglies(n,INT_MAX);
vector<int> idx(3,0);
int primers[]={2,3,5};
uglies[0] = 1;
for(int i=0;i<n;i++)
{
for(int j=0;j<3;j++)   uglies[i] = min(uglies[i],uglies[idx[j]]*primers[j]);
for(int j=0;j<3;j++)   idx[j]+=(uglies[i]==uglies[idx[j]]*primers[j]);
}
return uglies[n-1];
}
};


结果:28ms

2、一种更易读的方法,时间也更快,思路是一样的,只是写得形式不同而已。

代码地址:https://discuss.leetcode.com/topic/21882/my-16ms-c-dp-solution-with-short-explanation/2

class Solution {
public:
int nthUglyNumber(int n) {
if(n <= 0) return false; // get rid of corner cases
if(n == 1) return true; // base case
int t2 = 0, t3 = 0, t5 = 0; //pointers for 2, 3, 5
vector<int> k(n);
k[0] = 1;
for(int i  = 1; i < n ; i ++)
{
k[i] = min(k[t2]*2,min(k[t3]*3,k[t5]*5));
if(k[i] == k[t2]*2) t2++;
if(k[i] == k[t3]*3) t3++;
if(k[i] == k[t5]*5) t5++;
}
return k[n-1];
}
};


结果:16ms
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 算法 日记