leetcode题解日练--2016.7.12
来源:互联网 发布:手机上传淘宝主图视频 编辑:程序博客网 时间:2024/05/22 12:19
日练三题,冰冻三尺非一日之寒。
今日题目:1、二叉树每层最右节点;2、实现BST迭代器;3、最小路径和;❤4、超级丑数。
今日摘录:
我们要轻轻的走路、用心的过活;我们要温和的呼吸、柔软的关怀;我们要深刻的思想、广大的慈悲:我们要爱惜一株青草、践地唯恐地痛。这些,都是修行。
——林清玄 《情深,万象皆深》
199. Binary Tree Right Side View | Difficulty: Medium
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
For example:
Given the following binary tree,
1 <—
/ \
2 3 <—
\ \
5 4 <—
You should return [1, 3, 4].
题意:从上至下输出从右往左看能看到的那些节点。
思路:
1、BFS
突然想到之前一道类似的题目,用两个队列实现如下,权当练手。
/** * 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: vector<int> rightSideView(TreeNode* root) { queue <TreeNode*> q[2]; TreeNode *tmp; vector<int> res; if(!root) return res; int cur=0,next=1; q[cur].push(root); while(!q[cur].empty()||!q[next].empty()) { tmp = q[cur].front(); q[cur].pop(); if(tmp->left) q[next].push(tmp->left); if(tmp->right) q[next].push(tmp->right); if(q[cur].size()==0) { res.push_back(tmp->val); swap(cur,next); } } return res; }};
结果:4ms
其实一个队列就能搞定了,上述代码纯属搞笑。
/** * 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: vector<int> rightSideView(TreeNode* root) { queue <TreeNode*> q; TreeNode *tmp; vector<int> res; if(!root) return res; q.push(root); while(!q.empty()) { int end = q.size()-1; for(int i=0;i<=end;i++) { tmp = q.front(); q.pop(); if(tmp->left) q.push(tmp->left); if(tmp->right) q.push(tmp->right); if(i==end) res.push_back(tmp->val); } } return res; }};
结果:4ms
2、DFS
/** * 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: vector<int> rightSideView(TreeNode* root) { vector<int>res; recursion(res,1,root); return res; } void recursion(vector<int>&res,int level,TreeNode* root) { if(!root) return; if(res.size()<level) res.push_back(root->val); recursion(res,level+1,root->right); recursion(res,level+1,root->left); }};
结果:4ms
173. Binary Search Tree Iterator | Difficulty: Medium
Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.
Calling next() will return the next smallest number in the BST.
Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.
题意:实现一个BST的迭代器,使得能够在O(1)时间O(h)空间内调用是否有下一个最小数和下一个最小数是什么的功能。
思路:如果没有O(h)空间限制,我们完全可以在先中序遍历一次BST存入队列中,然后这个时候就已经排序好了,之后就很好办了。既然不能采用这种方法,那还有什么方法呢?不难想到,中序遍历的迭代实现是怎样呢?先将最左路径的元素存入栈中,然后从底开始访问,每次访问节点如果有右子树就将右子树的最左路加进来。照着这个思路就很好写代码了,我们需要一个将最左路加入到栈中的代码。
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class BSTIterator {public: stack<TreeNode*> nodes; BSTIterator(TreeNode *root) { pushLeftPath(root,nodes); } /** @return whether we have a next smallest number */ bool hasNext() { return !nodes.empty(); } /** @return the next smallest number */ int next() { TreeNode *tmp = nodes.top(); nodes.pop(); if(tmp->right) pushLeftPath(tmp->right,nodes); return tmp->val; }private: void pushLeftPath(TreeNode *root,stack<TreeNode*>&nodes) { while(root) { nodes.push(root); root = root->left; } }};/** * Your BSTIterator will be called like this: * BSTIterator i = BSTIterator(root); * while (i.hasNext()) cout << i.next(); */
结果:28ms
64. Minimum Path Sum | Difficulty: Medium
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.
题意:m×n的方格,每个方格都放了非负整数,找到一条从左上到右下的路径使得和最小。
相似题目:
思路:
1、很明显的DP思路。用了两个额外的向量。
class Solution {public: int minPathSum(vector<vector<int>>& grid) { int res=0; if(grid.size()==1) { for(int i=0;i<grid[0].size();i++) res+=grid[0][i]; return res; } else if(grid[0].size()==1) { for(int i=0;i<grid.size();i++) res+=grid[i][0]; return res; } int m=grid.size(); int n=grid[0].size(); vector<int> pre(m,INT_MAX); vector<int> cur(m,0); for(int i=0;i<n;i++) { if(i==0) cur[0] = grid[i][0]; else cur[0] = pre[0]+grid[0][i]; for(int j=1;j<m;j++) cur[j] =grid[j][i]+ min(pre[j],cur[j-1]); swap(pre,cur); } return pre[m-1]; }};
结果:12ms
上述代码写得太复杂了,每次都是一列一列进行计算,并且空间上还可以优化一下,下面简化一下代码:
class Solution {public: int minPathSum(vector<vector<int>>& grid) { int m=grid.size(); int n=grid[0].size(); vector<int> cur(m,grid[0][0]); for(int i=1;i<m;i++) { cur[i]=cur[i-1]+grid[i][0]; } for(int i=1;i<n;i++) { cur[0] +=grid[0][i]; for(int j=1;j<m;j++) cur[j] =grid[j][i]+min(cur[j-1],cur[j]); } return cur[m-1]; }};
结果:12ms
313. Super Ugly Number | Difficulty: Medium
Write a program to find the nth super ugly number.
Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4.
Note:
(1) 1 is a super ugly number for any given primes.
(2) The given numbers in primes are in ascending order.
(3) 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000.
题意:找到第n个超级丑数,超级丑数的定义是给了一个数组,超级丑数的所有因数只能是这个数组中的元素。
思路:
primes = [2,7,13,19] ,我们怎么样去找丑数?
首先可以肯定所有丑数肯定是2、7、13、19的倍数中产生,但是这里面是有重复元素的,我们需要做的事情就是将这些所有primes元素倍数的数按照从小到大拍个序
为了方便计数,我们创建一个与primes相同大小的idx数组[0,0,0,0],这个数组的含义是prime出现的次数。我们找第1个数(从0开始计数)的时候是怎么找的?这个时候遍历4个idx的值,代表primes中的元素出现的次数,这个时候全部都没有出现过,所以只需要拿1去与它们相乘然后找出最小的那个因子更新uglies[1] = min(primes[j]*uglies[idx[j]])遍历j。这个时候uglies[1] = 2,此时我们就用了一次2这个因子了,就应该将相应的idx加1,变成idx=[1,0,0,0],在下次遍历j的时候,uglies[idx[i]]就便成了[2,1,1,1]。
感觉好像没说清楚,其实就是[1,1,1,1]然后每个数乘上自己对应的因子,变成[2,7,13,19],挑出最小的作为丑数的下一个元素并且更新,其他均不更新。此时就变成[2,1,1,1],直到找够n个数字循环结束。
class Solution {public: int nthSuperUglyNumber(int n, vector<int>& primes) { vector<int> idx(primes.size(),0); vector<int> uglies(n,INT_MAX); uglies[0] = 1; for(int i=1;i<n;i++) { for(int j=0;j<primes.size();j++) uglies[i] = min(uglies[i],uglies[idx[j]]*primes[j]); for(int j=0;j<primes.size();j++) idx[j] +=(uglies[i]==uglies[idx[j]]*primes[j]); } return uglies[n-1]; }};
结果:168ms
- leetcode题解日练--2016.7.12
- leetcode题解日练--2016.7.1
- leetcode题解日练--2016.7.2
- leetcode题解日练--2016.7.3
- leetcode题解日练--2016.7.4
- leetcode题解日练--2016.7.5
- leetcode题解日练--2016.7.6
- leetcode题解日练--2016.7.7
- leetcode题解日练--2016.7.8
- leetcode题解日练--2016.7.9
- leetcode题解日练--2016.7.10
- leetcode题解日练--2016.7.11
- leetcode题解日练--2016.7.13
- leetcode题解日练--2016.7.14
- leetcode题解日练--2016.7.15
- leetcode题解日练--2016.7.16
- leetcode题解日练--2016.7.17
- leetcode题解日练--2016.7.18
- android developer tiny share-20160712
- ACM集训day2
- JNI
- div写自适应表格
- 有什么值得一看的燃到爆的电影?
- leetcode题解日练--2016.7.12
- 剑指offer 牛客网错题记录 四
- hdu1503 -Advanced Fruits
- 内存映射文件处理大文件
- 输入输出流
- [TJOI&HEOI2016]seq/[JZOJ4606]序列
- 使用virtualenv独立python环境
- KMP再思考
- cf 102 A(暴力)