面经准备-旷视

Posted cookcoder-mr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面经准备-旷视相关的知识,希望对你有一定的参考价值。

一.  字符的全排列

   对一个数组进行全排列,无重复元素,定义递归函数为前i-1个元素全排列已经排好, 将第i个元素以及后面的元素进行全排列。过程为从第i个元素到最后一个元素轮流放在第i个位置上, 然后对第i+1个元素以及后续元素进行全排列。

class Solution 
public:
    vector<vector<int>> permute(vector<int>& nums) 
        vector<vector<int>> res;
        permutehelper(nums, 0, res);
        return res;
    

private:
    void permutehelper(vector<int>&nums, int l, vector<vector<int>> &res)
        if (l == nums.size()) 
            res.push_back(nums);       
       for (int i = l; i < nums.size(); i++) 
                swap(nums[l], nums[i]);
                permutehelper(nums, l+1, res);
                swap(nums[i], nums[l]);
            
   
      

;

 

二. 大整数的乘法 leetcode43 MultiStrings

  大整数的乘法分为两步, 第一步将第一个大整数乘以第二个大bit的每个位。 注意后面要补0, 第二个步将第一步的中间结果实现一个大数加法。

 第一个trick。实现的时候用一个vector<int> 最后再统一处理进位和转成字符串。

class Solution 
public:
    string multiply(string num1, string num2) 
        if (num1 == "0" || num2 == "0") return "0";
        int len_1 = num1.size();
        int len_2 = num2.size();
        vector<string> holdMul;
        for (int i=0; i<len_2; i++)
            string tmp= "";
            tmp = num2[len_2 - 1 -i];
            string fillZero(i, 0);
            holdMul.push_back(mulOnebit(num1, tmp) + fillZero);
         
        string sum=holdMul[0];
        for  (int j=1; j< holdMul.size(); j++) 
            sum = addStr(sum, holdMul[j]);
            
        
        return sum;      
    
    
private:  
    string addStr(string a, string b) 
        reverse(a.begin(), a.end());
        reverse(b.begin(), b.end());
        int i = 0;
        int j = 0;
        vector<int> result;
        while(i< a.size() && j < b.size()) 
           result.push_back((a[i++] - 0)  +  (b[j++] - 0));         
        
        while(i < a.size()) result.push_back(a[i++] - 0);
        while(j < b.size()) result.push_back(b[j++] - 0);
        string re =  convertNumber(result);
        return re;
        
    
    string mulOnebit(string a, string b) 
        vector<int> result;
        for(int i=a.size() -1; i >= 0; i--)
            result.push_back((a[i] - 0) * (b[0] - 0));
            cout << result.back()<< " ";
        
        string re = convertNumber(result);
        return re;
        
    
    string convertNumber(vector<int> input) 

        int len = input.size();
        for(int i = 0; i < len; i++)            
            if (input[i] >= 10) 
                if (i < len - 1)
                input[i + 1] += (input[i] / 10); 
                
                else 
                   input.push_back(input[i] / 10);
                
                input[i] %= 10;
                       
        

        reverse(input.begin(), input.end());
        string result(input.size(), 0);
        for (int i=0; i< result.size(); i++) 
            result[i] += input[i];
        
            
        return result;
        
    
    
;

 

三. 完全二叉树如何高效插入

https://blog.csdn.net/fangjian1204/article/details/39179343

https://www.cnblogs.com/qieerbushejinshikelou/p/3917019.html

(1) O(n)的解法,采用一个queue层次遍历二叉树,取出来最右边的node插入

  (2)   O(logn * logn)的解法,递归。判断左右子树的高度,若左子树h大于右子树的h,则在左子树里面找,否则在右子树里面找

TreeNode* getLastNode(TreeNode* root) 
           If (root == NULL || root ->left == NULL)  return root;
            int lh = 0;
            TreeNode* p = root;
            while(p) 
               lh++;
               p = p-> left;
          
            Int rh = 0
             p = root;
             while(p) 
               rh++;
               p = p->right;
           

           If (lh > rh) return getLastNode(root->left);
           else return getLastNode(root->right);

(3) O(logn)的方法

 先统计树的深度,从右子树开始搜,一直向左搜到叶子结点,

 如果右子树的深度 < 全树深,则回到左子树上搜索

否则如果搜到叶子结点对应的根结点没有右孩子, 则返回该叶子结点。

        如果搜到的叶子结点对应的根结点有有孩子,则在右子树搜索。

TreeNode* getLastNode(TreeNode* root) 

          If (root ==NULL || root->left == NULL) return root;
          int height =0;
          TreeNode*p = root;
          while(p) 
              height++;
              p = p->next; 
         
         int level = 0;
         while(root) 
                 level++;
                 If (level == height) break;  // 右子树为空的情况。
                If (root->right) 
                Int tmp_len = level;
                 p = root;
                TreeNode *leaf = root->right;
                      while(leaf) 
                             tmp_len++;
                             p = leaf;
                            leaf = leaf ->left;
                      
                     If (tmp_len < height)  root = root->left;
                     else if (p->right == NULL || p->right == leaf) return leaf;
                     else root = root->right;

              
              else root = root->left;
             
         
         return root;

 

四. 设计LRU

 

五. 在几亿个大小的数组中选出最大的k个数字

 

六. 单链表排序 leetcode 146

class Solution 
public:// 归并排序 找中点
    ListNode* sortList(ListNode* head) 
        if(head == NULL || head->next == NULL) return head;
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast->next && fast->next->next) 
            fast = fast->next->next;
            slow = slow->next;
        
        
        fast = slow->next;
        if(slow->next)
        slow->next = NULL;
        ListNode* l1 = sortList(head);
        ListNode* l2 = sortList(fast);
        return merge(l1, l2);
    
private: 
    ListNode* merge(ListNode* p1, ListNode* p2) 
        ListNode* p0 = new ListNode(0);
        if(p1 == NULL) return p2;
        if(p2 == NULL) return p1;
        ListNode* p = p0;
        while(p1 || p2) 
            int temp1 = (p1 == NULL ? INT_MAX : p1->val);
            int temp2 = (p2 == NULL ? INT_MAX : p2->val);
            if(temp1 <= temp2) 
                p->next = p1;
                p1 = p1->next;
                p = p->next;
             else 
                p->next = p2;
                p2 = p2->next;
                p = p->next;
            
        
        /*if(p1)
            p->next = p1;
        
        if(p2)
            p->next = p2;
        */
        return p0->next;
    
;

七. 合并两个有序链表

class Solution 
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) 
        if (l1 == NULL) return l2;
        if (l2 == NULL) return l1;
        ListNode * head = new ListNode(0);
        ListNode * p = head;
        while (l1 != NULL && l2 != NULL) 
            if (l1->val <= l2->val) 
                p->next = l1;
                l1 = l1->next;
            
            else 
                p->next = l2;
                l2 = l2->next;
            
            p = p->next;
        
        if (l1) 
            p->next = l1;
        
        if (l2) 
            p->next = l2;
        
        ListNode * tmp = head->next;
        delete head;
        return tmp;
    
;

 

八. 青蛙跳

    问跳到第n个台阶有几种跳法

    每次跳一步或者两步

lass Solution 
public:
    int jumpFloor(int number) 
        if (number == 0) return 0;
        if (number == 1) return 1;
        if (number == 2) return 2;
        int pre_1 = 1;
        int pre_2 = 2;
        int re;
        for (int i=3; i<=number; i++)
            re = pre_1 + pre_2;
            pre_1 = pre_2;
            pre_2 = re;
        
        return re;
    
;

    每次可以跳n步

class Solution 
public:
    int jumpFloorII(int number) 

         vector<int> record(number+1, 0);
         record[0] =1;
         for (int i = 1; i<= number; i++)
             for(int j=0; j< i; j++)
                 record[i] += record[j];
         
            
        return record[number];    
    
;

 

九. 输出矩阵的外围元素,类似剑指offer的顺时针打印矩阵

class Solution 
public:
    vector<int> printMatrix(vector<vector<int> > matrix) 
        vector<int> result;
        int m = matrix.size();
        if (m==0) return result;
        int n = matrix[0].size();
        if (n==0) return result;
        int start=0;
        while(start < m/2.0 && start < n/2.0) 
           printCircle(matrix, start, m, n, result);
           start++;
        
        return result;
    
// 先判断问题,拆成print Circle, 
// 确定起点和终点的变化(看坐标,起点和终点的坐标和相同)
// 四个顺序,除了第一个,剩下的都是有条件的,并且要执行后一个必须要满足前面所有的条件。
private:
    void printCircle(vector<vector<int>> matrix, int start, int m, int n, vector<int> & result)
         int end_x = n - 1 - start;
         int end_y = m - 1 - start;
         // 从左到右
         for (int i = start; i <= end_x; i++)
         result.push_back(matrix[start][i]);
         // 从上到下
         if (end_y > start) 
             for (int i = start+1; i <= end_y; i++)
                 result.push_back(matrix[i][end_x]);
         
         // 从右到左
         if (end_x - 1 >= start && end_y > start) 
             for (int i= end_x-1; i>=start; i--)
                 result.push_back(matrix[end_y][i]);
         
         // 从下到上
        if (end_y - 1 > start && end_x -1 >= start) 
            for (int i= end_y - 1; i>= start+1; i--)
                result.push_back(matrix[i][start]);
        
    
;

 

大数组里某个数第一次出现的位置

 

八. 二叉树的前序,中序和后序序列的转换算法,有实现限制

 

九. 最短路径

 

十. 两行扫雷,给出第二行,判断第一行是不是有雷

 

十一. 公共子树的最进 O(h)

 

十二. 一维的max_pooling

 

 

十三.  生成矩阵

 

以上是关于面经准备-旷视的主要内容,如果未能解决你的问题,请参考以下文章

Bloomberg面经准备: Josephus problem

每日面经IntuitMicrosoftAmazon最新面经速递!

每日面经AmazonMicrosoftGoogle等最新面经速递!

每日面经BloombergMicrosoft等公司最新面经速递!

每日面经LinkedInMicrosoft​Spectrum​最新面经速递!

每日面经Microsoft​Amazon最新面经速递!