网易面试题

[编程题]寻找第K大

有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。

给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。

测试样例:
[1,3,5,2,2],5,3
返回:2

class Finder {
public:
    int findKth(vector<int> a, int n, int K) {
        // write code here
        return find(a,0,n-1,K);
        
    }
    int find(vector<int>& a, int left, int right, int K)
    {
        int begin=left;
        int end=right;
        int flag=a[left];
        while(left<right)
        {
            while(left<right&&a[right]<=flag)
                right--;
            if(left<right)
                a[left++]=a[right];                
            while(left<right&&a[left]>=flag)
                left++;
            if(left<right)
                a[right--]=a[left];
        }
        a[left]=flag;
        if(left-begin==K-1)
            return a[left];
        else if(left-begin>K-1)
            return find(a,begin,left-1,K);
          
        else
            return find(a,left+1,end,K-(left-begin)-1);
         
   
    }
};

 剑指offer上的解法如下,更加的简洁:

class Finder {
public:
    int findKth(vector<int> a, int n, int K) {
        // write code here
        int start=0;
        int end=n-1;
        int index=find(a,0,n-1);
        while(index!=K-1)
        {
            if(index>K-1)
            {
                end=index-1;
                index=find(a,start,end);
            }
            else if(index<K-1)
            {
                start=index+1;
                index=find(a,start,end);
            }
        }
        return a[index];
         
    }
    int find(vector<int>& a, int left, int right)
    {
        int begin=left;
        int end=right;
        int flag=a[left];
        while(left<right)
        {
            while(left<right&&a[right]<=flag)
                right--;
            if(left<right)
                a[left++]=a[right];                
            while(left<right&&a[left]>=flag)
                left++;
            if(left<right)
                a[right--]=a[left];
        }
        a[left]=flag;
        return left;
         
   
    }
};
[编程题]二叉树

有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。

给定二叉树的根节点root,请返回所求距离。

/*

struct TreeNode {

    int val;

    struct TreeNode *left;

    struct TreeNode *right;

    TreeNode(int x) :

            val(x), left(NULL), right(NULL) {

    }

};*/



class Tree {

public:

    vector<int> pathTemp;

    

public:

    int getDis(TreeNode* root) {

        // write code here

        if(root==NULL)

            return 0;

        int Max=0x80000000,Min=0x7fffffff;

        vector<int> pathMax,pathMin;

        getMaxMin(root,Max,Min);

        

        getPath(root,Max,pathMax);

        pathMax=pathTemp;
        pathTemp.clear();
       

        getPath(root,Min,pathMin);

        pathMin=pathTemp;

        return getLc(pathMax,pathMin);

 

    }

    void getMaxMin(TreeNode* root,int&Max,int&Min){

        if(root->left==NULL&&root->right==NULL)

        {

            if(root->val>Max)

                Max=root->val;

            if(root->val<Min)

                Min=root->val;

            return ;

        }

        if(root->left!=NULL)

            getMaxMin(root->left,Max,Min);

        if(root->right!=NULL)

            getMaxMin(root->right,Max,Min);

        return ;

    }

    void getPath(TreeNode* root,const int&num,vector<int>&res)

    {

        if(root==NULL)

            return;

        res.push_back(root->val);

        if(root->left==NULL&&root->right==NULL)

        {

             if(root->val==num)

            {

                pathTemp=res;

                return ;

            

            }

        }         

        else

        {

            if(root->left!=NULL)

                getPath(root->left,num,res);

            if(root->right!=NULL)

                getPath(root->right,num,res);

        }

        res.pop_back();

        return ;

    }

    int getLc(vector<int> pathMax,vector<int> pathMin)

    {

        int len1=pathMax.size();

        int len2=pathMin.size();

      

        int res=0;

        if(len1>len2)

        {

           

            for(int i=0;i<len2;i++)

            {

                if(pathMax[i]!=pathMin[i])

                {

                    res=i;

                    break;

                }

                    

            }

        }

        else if(len1<=len2)

        {

         

            for(int i=0;i<len1;i++)

            {

                if(pathMax[i]!=pathMin[i])

                {

                    res=i;

                    break;

                }

                    

            }

        }

        return len1+len2-2*res;

            

    }

};
//千万要注意最大值最小值的设定
[编程题]比较重量

小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量。这些钻石的重量各不相同。在他们们比较了一段时间后,它们看中了两颗钻石g1和g2。现在请你根据之前比较的信息判断这两颗钻石的哪颗更重。

给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第 二个元素为较轻的钻石的编号。最后给定之前的比较次数n。请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0。输入数据保证合 法,不会有矛盾情况出现。

测试样例:
2,3,[[1,2],[2,4],[1,3],[4,3]],4
返回: 1
class Cmp {
public:
    int cmp(int g1, int g2, vector<vector<int> > records, int n) {
        // write code here
        map<int,vector<int>> res;
        for(int i=0;i<n;i++)
            res[records[i][0]].push_back(records[i][1]);
        if(juge(g1,g2,res))
            return 1;
        else if(juge(g2,g1,res))
            return -1;
        else
            return 0;
    }
    bool juge(const int &g1,const int &g2,map<int,vector<int>> res)
    {
        queue<int> q;
        q.push(g1);
        map<int,bool> mark;
        while(!q.empty())
        {
            int cur=q.front();
            q.pop();
            mark[cur]=true;
            if(cur==g2)
                return true;
            for(int i=0;i<res[cur].size();i++)
            {
                if(mark.find(res[cur][i])==mark.end())
                    q.push(res[cur][i]);
            }
            
            
        }
        return false;
    }
};
[编程题] 小易的升级之路

小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3...bn. 如果遇到的怪物防御力bi小于等于小易的当前能力值c,那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi 与c的最大公约数.那么问题来了,在一系列的锻炼后,小易的最终能力值为多少?

输入描述:
对于每组数据,第一行是两个整数n(1≤n<100000)表示怪物的数量和a表示小易的初始能力值.
第二行n个整数,b1,b2...bn(1≤bi≤n)表示每个怪物的防御力


输出描述:
对于每组数据,输出一行.每行仅包含一个整数,表示小易的最终能力值
输入例子:
3 50
50 105 200
5 20
30 20 15 40 100
#include<iostream>
#include<vector>
using namespace std;
int getRes(const vector<int>&vec,const int& num,int b );
int main()
{
    int num,b;
    while(cin>>num)
    {
        cin>>b;
        vector<int> vec(num);
        for(int i=0;i<num;i++)
        {
            cin>>vec[i];
        }
        int res=getRes(vec,num,b);
        cout<<res<<endl;
    }
    return 0;
}
int getRes(const vector<int>&vec,const int& num,int b )
{
    for(int i=0;i<num;i++)
    {
        if(vec[i]<=b)
            b+=vec[i];
        else
        {
            int small=b,big=vec[i];
            int rest=big%small;
            while(rest!=0)
            {
                big=small;
                small=rest;
                rest=big%small;
            }
            b+=small;
        }
    }
    return b;
}
原文地址:https://www.cnblogs.com/qiaozhoulin/p/5740073.html