2021春招刷题

二叉树

给你一个二叉树的根节点 root ,返回其最大路径和

class Solution {
private:
    int ans=INT_MIN;
public:
    int maxNodeGain(TreeNode* root)
    {
        if(root==nullptr)
            return 0;
        int left = max(0,maxNodeGain(root->left));
        int right = max(0,maxNodeGain(root->right));
        int maxNodePath = left + right + root->val;
        ans = max(ans,maxNodePath);
        return max(left,right)+root->val;
    }
    int maxPathSum(TreeNode* root) {
        maxNodeGain(root);
        return ans;
    }
};

数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        int n = nums.size();
        for(int i = 0; i < n; i++){
            int k = nums[i];
            if(k < 0) k += n;
            if(nums[k] < 0) return k;
            nums[k] -= n;
        }        
        return -1;
    }
};                        

二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

class Solution {
public:
    bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) {
        if(matrix.empty())
        {
            return 0;
        }
        int n=matrix.size();//行
        int m=matrix[0].size();//如果不加上面的empty,这边的matrix[0]就会内存溢出
        int i=n-1;
        int j=0;
        while((i>=0)&&(j<m))
        {
            int num=matrix[i][j];
            //cout<<num;
            if(target<num)
            {
                i--;
            }
            
            else if(target>num)
                j++;
            else return true;
        }        
        return false;
         /*int i = matrix.size() - 1, j = 0;
        while(i >= 0 && j < matrix[0].size())//这种情况下空矩阵的时候,执行完i>=0就会退出,不会执行后面的语句
        {
            if(matrix[i][j] > target) i--;
            else if(matrix[i][j] < target) j++;
            else return true;
        }
        return false;*/
    }
};

替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
思路:先计算有多少个字符,再找出有多少个空格,空格变成%20后,长度会增加,从后面开始往前遍历

class Solution {
public:
    string replaceSpace(string s) {
        int count=0,len=s.size();
        for(char c:s)
        {
            if(c==' ')
                count++;
        }
        s.resize(len+2*count);
        for(int i=len-1,j=s.size()-1;i<j;i--,j--)
        {
            if(s[i]!=' ')
                s[j]=s[i];
            else
            {
                s[j-2]='%';
                s[j-1]='2';
                s[j]='0';
                j-=2;
            }
        }
        return s;
    }
};

从头到尾打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
解一:反转

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> res;
        while(head){
            res.push_back(head->val);
            head=head->next;
        }
        reverse(res.begin(),res.end());
        return res;

    }
};

解二:堆栈

class Solution {
public:
    vector<int> reversePrint(ListNode* head) {
        vector<int> res;
        stack<int> s;
        while(head)
        {
            s.push(head->val);
            head=head->next;
        }
        while(!s.empty())
        {
            res.push_back(s.top());
            s.pop();
        }
        return res;
    }
};

重建二叉树

重建二叉树:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
递归

class Solution {
private:
    unordered_map<int, int> index;

public:
    TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
        if (preorder_left > preorder_right) {
            return nullptr;
        }
        
        // 前序遍历中的第一个节点就是根节点
        int preorder_root = preorder_left;
        // 在中序遍历中定位根节点
        int inorder_root = index[preorder[preorder_root]];
        
        // 先把根节点建立出来
        TreeNode* root = new TreeNode(preorder[preorder_root]);
        // 得到左子树中的节点数目
        int size_left_subtree = inorder_root - inorder_left;
        // 递归地构造左子树,并连接到根节点
        // 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
        root->left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
        // 递归地构造右子树,并连接到根节点
        // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
        root->right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n = preorder.size();
        // 构造哈希映射,帮助我们快速定位根节点
        for (int i = 0; i < n; ++i) {
            index[inorder[i]] = i;
        }
        return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
    }
};

用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

class CQueue {
    stack<int> stack1,stack2;
public:
    CQueue() {
        while(!stack1.empty())
        {
            stack1.pop();
        }
        while(!stack2.empty())
        {
            stack2.pop();
        }

    }
    
    void appendTail(int value) {
        stack1.push(value);
    }
    
    int deleteHead() {
        if(stack2.empty())
        {
            while(!stack1.empty())
            {
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        if(stack2.empty())
        {
            return -1;
        }
        else
        {
            int deletenum = stack2.top();
            stack2.pop();
            return deletenum;
        }
    }
};

剑指offer10-1

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

class Solution {
public:
    int fib(int n) {
        int m=0;
        if(n==0)return 0;
        if(n==1)return 1;
        int a=0,b=1;
        if(n>1)
        {
            
            for(int i=1;i<n;i++)
            {
                int temp=a%1000000007;
                a=b%1000000007;
                b=(a+temp)%1000000007;
            }    
        }     
         return b;
    }    
};

剑指offer10-2

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
本质还是斐波那契数列问题

class Solution {
public:
    int numWays(int n) {
        if(n==0||n==1)return 1;
        int a=1,b=1,c=0;
        if(n>1)
        {
            for(int i=1;i<n;i++)
            {
                c=(a+b)%1000000007;
                a=b;
                b=c;
            }
        }
        return c;
    }
};

旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

class Solution {
public:
    int minArray(vector<int>& numbers) {
        int j=0;
        //cout<<numbers.size();
        for(int i=0;i<numbers.size()-1;i++)
        {
            
            if(numbers[i]>numbers[i+1])
            {
                j =i+1;
            }
        }
       
       // cout<<j;
    return numbers[j];
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值