【C++】面经,旋转数组的最小数字,比较版本号,二叉树的前序遍历,中序,后序,层序

目录

1.旋转数组的最小数字

2.比较版本号

3.二叉树的前序遍历

 4.中序遍历

5.后序遍历

6.层序


1.旋转数组的最小数字

二分查找有序数组中的数字,有序数组的旋转数组也可以二分找

 

如果left<=right 那么相遇进去之后只能返回left ,考虑一下最后mid=left=right=0;如果进去了,right--直接变成-1,不可能返回下标-1的元素

left<right,不需要担心这个问题,直接返回下标left/right元素

class Solution {
public:
    //默认区间升序
    int minNumberInRotateArray(vector<int> rotateArray) {
        int left = 0, right = rotateArray.size() - 1; //左右区间
        while (left < right) //条件判断,让相遇的时候直接出来
        {
            int mid = (left + right) / 2; //中间点
            if (rotateArray[mid] < rotateArray[right]) //mid更小说明最小在左区间
                right = mid;
            else if (rotateArray[mid] > rotateArray[right]) //mid更大说明最小在右区间
                left = mid + 1;
            else right--; //没有比较出大小,缩小搜索范围继续找

        }
        return rotateArray[left]; //相遇点,返回left/right
    }
};

2.比较版本号

其实看他描述的很复杂,就是挨个比较每个.前后的数字大小

 

 

int compare(string version1, string version2) {
    // write code here
    int  p = 0, q = 0, n1 = version1.size(), n2 = version2.size(); //p,q代表两个版本号的起始(遍历)下标,
    int t1 = 0, t2 = 0; //表示当前数值,比如1.1和1.21, 第一次比较t1=1,t2=1,第二次t1=1,t2=21
    while (p < n1 || q < n2)  //任意一个不结束都要再比较,1和1.1.1,要一直比较到1.1.1遍历结束
    {
        t1 = 0, t2 = 0;  //每次都清空之前的
        while (p < n1 && version1[p++] != '.')  //走到.停止
        { 
            t1 = t1 * 10 + version1[p - 1] - '0'; //需要进位的,这个是固定写法,自己顺一遍就知道为什么这样
        }
        while (q < n2 && version2[q++] != '.')
        {
            t2 = t2 * 10 + version2[q - 1] - '0';
        }
        if (t1 < t2) return -1; //在这一部分能比较出大小就直接返回
        if (t1 > t2) return 1;
    }
    return 0;
}

3.二叉树的前序遍历


void _preorderTraversal(TreeNode* root, vector<int>& v)
{
    if (!root) return;
    v.push_back(root->val); //根
    _preorderTraversal(root->left, v); //左子树
    _preorderTraversal(root->right, v); //右子树

}
vector<int> preorderTraversal(TreeNode* root) {
    // write code here
    vector<int> v; //需要一个数组保存每个节点的值
    _preorderTraversal(root, v); //带着数组遍历
    return v;
}

 4.中序遍历

直接写就好啦,只是变成 左子树 根 右子树

       void _inorderTraversal(TreeNode* root,vector<int> &v)
     {
        if(!root) return;
      
        _inorderTraversal(root->left,v); 
         v.push_back(root->val);
        _inorderTraversal(root->right,v);
     
     }
    vector<int> inorderTraversal(TreeNode* root) {
        // write code here
          vector<int> v;
        _inorderTraversal(root, v);
         return v;
    }

5.后序遍历

         void _postorderTraversal(TreeNode* root,vector<int> &v)
     {
        if(!root) return;
      
        _postorderTraversal(root->left,v); 
       
        _postorderTraversal(root->right,v);
       v.push_back(root->val);
     }
    vector<int> postorderTraversal(TreeNode* root) {
        // write code here
        vector<int> v;
        _postorderTraversal(root, v);
         return v; 
    }

6.层序

第一个方法:前序递归

depth不是累加的所以不需要传引用;

void level(vector<vector<int> >& ans, TreeNode* root, int depth) {
    if (root == NULL)
        return;
    if (ans.size() > depth)
        ans[depth].push_back(root->val);
    else {
        vector<int> v;
        v.push_back(root->val);
        ans.push_back(v);
    }
    level(ans, root->left, depth + 1);
    level(ans, root->right, depth + 1);
}

vector<vector<int> > levelOrder(TreeNode* root) {
    // write code here
    vector<vector<int> > ans;
    level(ans, root, 0);
    return ans;
}

第二个常规方法,队列

 后面几层也是这样的

vector<vector<int> > levelOrder(TreeNode* root)
{
    vector<vector<int>> vv;//二维数组
    if (!root) //空树直接返回
        return vv;
    queue<TreeNode*> q; //用队列保留数据
    q.push(root); //把根尾插
    int size = 1; //记录队列的数据个数
    while (!q.empty()) //空队列说明数的数值都保存到数组了
    {
        vector<int> v; //保存每一层的元素值
        while (size--) //每转移一次就减少一个队列的元素个数
        {
            TreeNode* tmp = q.front(); //取队头数据
            v.push_back(tmp->val); //尾插这个节点的val
            q.pop(); //头删,导入之后就没用了
            //带入下一层的节点
            if (tmp->left) //左节点不为空
                q.push(tmp->left); //插入左节点
            if (tmp->right)
                q.push(tmp->right);
        }
        size = q.size();//size更新
        vv.push_back(v);//把整个这层的数组插入到二维数组
    }
    return vv;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值