目录
1.剑指Offer
面试题32:从上到下打印二叉树
题目描述:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
思路:层次遍历使用队列
代码:
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root) {
vector<int> res;
if(root==nullptr){
return res;
}
queue<TreeNode*> q;
q.push(root);
while(q.size()!=0){
TreeNode* pNode=q.front();
res.push_back(pNode->val);
q.pop();
if(pNode->left!=nullptr){
q.push(pNode->left);
}
if(pNode->right!=nullptr){
q.push(pNode->right);
}
}
return res;
}
};
面试题32:把二叉树打印成多行
题目描述:从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
代码:
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > res;
if(pRoot==nullptr){
return res;
}
queue<TreeNode*> q;
q.push(pRoot);
while(!q.empty()){
int n=q.size();
vector<int> temp;
while(n--){
TreeNode* pNode=q.front();
temp.push_back(pNode->val);
if(pNode->left!=nullptr){
q.push(pNode->left);
}
if(pNode->right!=nullptr){
q.push(pNode->right);
}
q.pop();
}
res.push_back(temp);
}
return res;
}
};
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > res;
vector<int> temp;
if(pRoot==nullptr){
return res;
}
queue<TreeNode*> q;
q.push(pRoot);
int tobeprint=1;
int nextlevel=0;
while(q.size()){
TreeNode* pNode=q.front();
temp.push_back(pNode->val);
if(pNode->left!=nullptr){
q.push(pNode->left);
nextlevel++;
}
if(pNode->right!=nullptr){
q.push(pNode->right);
nextlevel++;
}
q.pop();
tobeprint--;
if(tobeprint==0){
res.push_back(temp);
temp.clear();
tobeprint=nextlevel;
nextlevel=0;
}
}
return res;
}
};
解析:
1.vector::clear()函数的作用是清空容器中的内容,但如果是指针对象的话,并不能清空其内容,必须要像以下方法一样才能达到清空指针对象的内容,将会清空temp中的所有元素,包括temp开辟的空间(size),但是capacity会保留,即不可以以temp[1]这种形式赋初值,只能通过temp.push_back(value)的形式赋初值。
-
vector<int*> xx;
-
for(int it=0;it!=xx.size();++it)
-
{
-
delete xx[it];
-
}
-
xx.clear()
-
但并不回收内存,但你可以通过swap()函数来巧妙的达到回收内存的效果:
-
xx.clear();
-
xx.swap(vector<int>());
2、vector::erase()用于清空容器中的内容以及释放内存,并返回指向删除元素的下一个元素的迭代器。
面试题32:按之字形顺序打印二叉树
题目描述:
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:使用两个栈
代码:
class Solution {
public:
vector<vector<int> > Print(TreeNode* pRoot) {
vector<vector<int> > res;
if(pRoot==nullptr){
return res;
}
stack<TreeNode*> s[2];
int current=0;
int next=1;
s[current].push(pRoot);
while(!s[current].empty()||!s[next].empty()){
int n=s[current].size();
vector<int> temp;
while(n--){
TreeNode* pNode=s[current].top();
temp.push_back(pNode->val);
s[current].pop();
if(current==0){
if(pNode->left){
s[next].push(pNode->left);
}
if(pNode->right){
s[next].push(pNode->right);
}
}
else{
if(pNode->right){
s[next].push(pNode->right);
}
if(pNode->left){
s[next].push(pNode->left);
}
}
}
current=1-current;
next=1-next;
res.push_back(temp);
}
return res;
}
};
面试题36:二叉搜索树与双向链表
题目描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:中序遍历+递归
代码:
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(pRootOfTree==nullptr) return nullptr;
TreeNode* pLastNodeOfList=nullptr;
ConvertCore(pRootOfTree,pLastNodeOfList);
TreeNode* pHeadOfList=pRootOfTree;
while(pHeadOfList->left!=nullptr){
pHeadOfList=pHeadOfList->left;
}
return pHeadOfList;
}
void ConvertCore(TreeNode* pRootOfTree,TreeNode*& pLastNodeOfList){
if(pRootOfTree==nullptr){
return;
}
TreeNode* pCurrent=pRootOfTree;
if(pCurrent->left!=nullptr){
ConvertCore(pCurrent->left,pLastNodeOfList);
}
pCurrent->left=pLastNodeOfList;
if(pLastNodeOfList!=nullptr){
pLastNodeOfList->right=pCurrent;
}
pLastNodeOfList=pCurrent;
if(pCurrent->right!=nullptr){
ConvertCore(pCurrent->right,pLastNodeOfList);
}
}
};
3.华为机试题
例1:取近似值
题目描述:
写出一个程序,接受一个正浮点数值,输出该数值的近似整数值。如果小数点后数值大于等于5,向上取整;小于5,则向下取整。
输入描述:
输入一个正浮点数值
输出描述:
输出该数值的近似整数值
示例1
输入
5.5
输出
6
代码:
#include <iostream>
using namespace std;
int main(){
float a;
cin>>a;
cout<<int(a+0.5)<<endl;
return 0;
}
例2:合并表记录
题目描述:
数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。
输入描述:
先输入键值对的个数
然后输入成对的index和value值,以空格隔开
输出描述:
输出合并后的键值对(多行)
示例1
输入
4
0 1
0 2
1 2
3 4
输出
0 3
1 2
3 4
思路:map用法
代码:
#include <iostream>
#include <map>
using namespace std;
int main(){
int n;
while(cin>>n){
map<int,int> m;
while(n--){
int key,value;
cin>>key>>value;
if(!m[key]){
m[key]=value;
}
else{
m[key]+=value;
}
}
for(map<int,int>::iterator iter=m.begin();iter!=m.end();iter++){
cout<<iter->first<<" "<<iter->second<<endl; //注意输出格式,中间需要加空格
}
}
return 0;
}
例3:提取不重复的整数
题目描述:
输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
输入描述:
输入一个int型整数
输出描述:
按照从右向左的阅读顺序,返回一个不含重复数字的新的整数
示例1
输入
9876673
输出
37689
思路:使用a[10]数组用于判断数字是否重复出现。
代码:
#include <iostream>
using namespace std;
int main(){
int n;
while(cin>>n){
int a[10]={0};
int num=0;
while(n){
if(a[n%10]==0){
a[n%10]++;
num=num*10+n%10;
}
n=n/10;
}
cout<<num<<endl;
}
return 0;
}
解析:在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。