编程之旅-Day39

目录

Day39-学习内容:

1.剑指Offer

面试题32:从上到下打印二叉树

面试题32:把二叉树打印成多行

面试题32:按之字形顺序打印二叉树

面试题36:二叉搜索树与双向链表

 3.华为机试题

例1:取近似值

例2:合并表记录

例3:提取不重复的整数


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)的形式赋初值。

  1. vector<int*> xx;

  2. for(int it=0;it!=xx.size();++it)

  3. {

  4. delete xx[it];

  5. }

  6. xx.clear()

  7. 但并不回收内存,但你可以通过swap()函数来巧妙的达到回收内存的效果:

  8. xx.clear();

  9. 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中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。

猜你喜欢

转载自blog.csdn.net/linyuhan3232/article/details/89538892