牛客网编程2

时间:2022-09-09 09:48:32

1

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列45,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

解析:本题思路为:将入栈序列逐个加入,如果加入的等于出栈的,就将其加入后弹出,妙。

class Solution {

public:

    bool IsPopOrder(vector<int> pushV,vector<int> popV) {

        if(pushV.size() == 0) return false;

        vector<int> stack;

        for(int i = 0,j = 0 ;i < pushV.size();){

            stack.push_back(pushV[i++]);

            while(j < popV.size() && stack.back() == popV[j]){

                stack.pop_back();

                j++;

            }      

        }

        return stack.empty();

    }

};

2

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

解析:一时想不起二叉树的层次遍历.....脑子还真是笨。要判断好如果左右子树不是空才入对列。

class Solution {

public:

    vector<int> PrintFromTopToBottom(TreeNode *root) {

queue<TreeNode*> q;

    vector<int>result;

        if(root==NULL)

            return result;

        q.push(root);

        while(!q.empty()){

            TreeNode*p=q.front();

            q.pop();

            result.push_back(p->val);

            if(p->left!=NULL)

             q.push(p->left);

            if(p->right!=NULL)

             q.push(p->right);

        }

        return result;

            

        

    }

};

3

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同

解析:本题虽然想到了,序列中最后一个肯定为根,然后前面一部分为右子树(大于根),另一部分为左子树(小于根)。也想到递归解决,但是没想好到底怎么递归。

class Solution {

    bool judge(vector<int>& a, int l, int r){

        if(l >= r) return true;

        int i = r;

        while(i > l && a[i - 1] > a[r]) --i;

        for(int j = i - 1; j >= l; --j) if(a[j] > a[r]) return false;

        return judge(a, l, i - 1) && (judge(a, i, r - 1));

    }

public:

    bool VerifySquenceOfBST(vector<int> a) {

        if(!a.size()) return false;

        return judge(a, 0, a.size() - 1);

    }

};

4

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

class Solution {

public:

    vector<vector<int> >allRes;

    vector<int> tmp;

    void dfsFind(TreeNode * node , int left){

        tmp.push_back(node->val);

        if(left-node->val == 0 && !node->left && !node->right)

            allRes.push_back(tmp);//找到和为所给整数的,加入结果集。

        else {

            if(node->left) dfsFind(node->left, left-node->val);

            if(node->right) dfsFind(node->right, left-node->val);

        }

        tmp.pop_back(); //回退。

    }

public:

    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {

        if(root) dfsFind(root, expectNumber);

        return allRes;

    }

};

5

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

class Solution {

public:

    RandomListNode* Clone(RandomListNode* pHead)

    {

       

            

            

              if(pHead==NULL)

            return NULL;

        RandomListNode *pCur = pHead;

        //复制next 如原来是A->B->C 变成A->A'->B->B'->C->C'

        while(pCur!=NULL){

            RandomListNode *node = new RandomListNode(pCur->label);

            node->next = pCur->next;

            pCur->next = node;

            pCur = node->next;

        }

        pCur = pHead;

        //复制random pCur是原来链表的结点 pCur.next是复制pCur的结点

        while(pCur!=NULL){

            if(pCur->random!=NULL)

                pCur->next->random = pCur->random->next;

            pCur = pCur->next->next;

        }

        RandomListNode *head = pHead->next;

        RandomListNode *cur = head;

        pCur = pHead;

        //拆分链表

        while(pCur!=NULL){

            pCur->next = pCur->next->next;

            if(cur->next!=NULL)

                cur->next = cur->next->next;

            cur = cur->next;

            pCur = pCur->next;

        }

        return head;       

       

            

            

        

    }

};

6

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

本题递归,中序遍历二叉树,记录上一个节点,本节点左子树指向上一个节点,上一个节点右子树指向本节点。

class Solution {

public:

     TreeNode*pre=NULL;

     TreeNode*lastLeft=NULL;

    TreeNode* Convert(TreeNode* pRootOfTree)

    {

        if(pRootOfTree==NULL)

            return pRootOfTree;

         

         Convert(pRootOfTree->left);

          pRootOfTree->left=pre;

        if(pre!=NULL){

        pre->right=pRootOfTree;

        } 

        

        pre=pRootOfTree;

         

       lastLeft=lastLeft==NULL?pRootOfTree:lastLeft;//找到结果的开始地方。要么最左下,要么根节点。

         Convert(pRootOfTree->right);

        return lastLeft;

    }

};

 

 

7

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有110111213因此共出现6,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。

/*

N = abcde ,其中abcde分别为十进制中各位上的数字。

如果要计算百位上1出现的次数,它要受到3方面的影响:百位上的数字,百位以下(低位)的数字,百位以上(高位)的数字。

① 如果百位上数字为0,百位上可能出现1的次数由更高位决定。比如:12013,则可以知道百位出现1的情况可能是:100~1991100~1199,2100~2199,,...11100~11199,一共1200个。可以看出是由更高位数字(12)决定,并且等于更高位数字(12)乘以 当前位数(100)。

② 如果百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低位影响。比如:12113,则可以知道百位受高位影响出现的情况是:100~1991100~1199,2100~2199,,....11100~11199,一共1200个。和上面情况一样,并且等于更高位数字(12)乘以 当前位数(100)。但同时它还受低位影响,百位出现1的情况是:12100~12113,一共114个,等于低位数字(113+1

③ 如果百位上数字大于12~9),则百位上出现1的情况仅由更高位决定,比如12213,则百位出现1的情况是:100~199,1100~11992100~2199...11100~11199,12100~12199,一共有1300个,并且等于更高位数字+112+1)乘以当前位数(100)。

*/

public class Solution {

    public int NumberOf1Between1AndN_Solution(int n) {

        int count = 0;//1的个数

        int i = 1;//当前位

        int current = 0,after = 0,before = 0;

        while((n/i)!= 0){           

            current = (n/i)%10; //高位数字

            before = n/(i*10); //当前位数字

            after = n-(n/i)*i; //低位数字

            //如果为0,出现1的次数由高位决定,等于高位数字 * 当前位数

            if (current == 0)

                count += before*i;

            //如果为1,出现1的次数由高位和低位决定,高位*当前位+低位+1

            else if(current == 1)

                count += before * i + after + 1;

            //如果大于1,出现1的次数由高位决定,//(高位数字+1* 当前位数

            else{

                count += (before + 1) * i;

            }    

            //前移一位

            i = i*10;

        }

        return count;

    }

}

8

c++如何将int转为string

  for(int i=0;i<numbers.size();i++ ){

           stringstream ss;

            ss<<numbers[i];

            string s = ss.str();

            strNum.push_back(s);

        }