精华内容
下载资源
问答
  • 截至2019年4月17日 完成了华为的笔试-测评-技术面-综合面 ,并全部通过,顺利进入华为的录用排序,留帖纪念,具体面经在收到正式offer后更新。

    截至2019年4月17日 完成了华为的笔试-测评-技术面-综合面 ,并全部通过,顺利进入华为的录用排序,留帖纪念,具体面经在收到正式offer后更新。

    展开全文
  • 华为手撕代码总结1.1排序问题1.2链表求和1.3树的前中后序遍历(递归/循环写法)1.4树的链表化1.5给一个初始饮料瓶数,三个空瓶换一瓶,可以赊一瓶,求最后能喝几瓶1.6岛屿最大面积问题1.7自己面试手撕的5道算法题2....

    文章目录

    1.华为手撕代码总结

    1.1排序问题

    • 冒泡排序
    def bubbleSort(arr):
        n = len(arr)
        for i in range(n):
            for j in range(0, n-i-1):
                if arr[j] > arr[j+1] :
                    arr[j], arr[j+1] = arr[j+1], arr[j]
        return arr
    
    • 快排

    思路:快速排序基本思想是:如序列[6,8,1,4,3,9],选择6作为基准数。从右向左扫描,寻找比基准数小的数字为3,交换6和3的位置,[3,8,1,4,6,9],接着从左向右扫描,寻找比基准数大的数字为8,交换6和8的位置,[3,6,1,4,8,9]。重复上述过程,直到基准数左边的数字都比其小,右边的数字都比其大。然后分别对基准数左边和右边的序列递归进行上述方法。详细可见:https://www.jianshu.com/p/2b2f1f79984e

    def q_sort(L, left, right):
        if left < right:
            pivot = Partition(L, left, right)
            q_sort(L, left, pivot - 1)
            q_sort(L, pivot + 1, right)
        return L
    
    def Partition(L, left, right):
        pivotkey = L[left]
        while left < right:
            while left < right and L[right] >= pivotkey:
                right -= 1
            L[left] = L[right]
            while left < right and L[left] <= pivotkey:
                left += 1
            L[right] = L[left]
    
        L[left] = pivotkey
        return left
    

    1.2链表求和

    题目解析:
    3->1->5->null 
    5->9->2->null
    
    3+5=8
    1+9=10,得到的进位1到下一个节点,第二个节点为0
    1(上一个节点的进位)+5+2=8
    结果为:
    8->0->8->null
    

    代码实现:

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def addLists(self, l1, l2):
            #判断是否某一链表为None,是返回另一条
            if l1==None:return l2
            if l2 == None:return l1
            h1=l1
            h2=l2
            #只有两个链表的下一个节点数都为None,退出循环
            while h1.next is not None or h2.next is not None:
                #若只有一条链表的下一个节点为None,补充为0,不影响后续的加法结果
                if h1.next ==None:h1.next=ListNode(0)
                if h2.next ==None:h2.next=ListNode(0)
                h1.val=h1.val+h2.val
                #当加结果>=10,当前结果节点为个位数,下一个节点+1
                if h1.val>=10:
                    h1.val=h1.val%10
                    h1.next.val+=1
                h1=h1.next
                h2=h2.next
            else:
                h1.val=h1.val+h2.val
                #链表尾部的计算,如果>=10,则在尾部再添加一个节点
                if h1.val>=10:
                    h1.val=h1.val%10
                    h1.next=ListNode(1)
            return l1
    

    1.3树的前中后序遍历(递归/循环写法)

    • 递归
    class Solution:
        def inorderTraversal(self, root):   #中序遍历
            if not root:
                return [] 
            return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
    
        def preorderTraversal(self, root):  #前序遍历
            if not root:
                return [] 
            return  [root.val] + self.inorderTraversal(root.left) + self.inorderTraversal(root.right)
            
        def postorderTraversal(self, root):  #后序遍历
            if not root:
                return [] 
            return  self.inorderTraversal(root.left) + self.inorderTraversal(root.right) + [root.val]
    
    • 循环实现

    原理详细解释:https://www.cnblogs.com/bjwu/p/9284534.html

    class Solution:
        def inorderTraversal(self, root):    #中序遍历
            stack = []    #用栈实现
            sol = []      #结果
            curr = root    #节点运动位置
            while stack or curr:
                if curr:
                    stack.append(curr)
                    curr = curr.left
                else:
                    curr = stack.pop()
                    sol.append(curr.val)
                    curr = curr.right
            return sol
            
         def preorderTraversal(self, root):   # 前序遍历
            stack = []
            sol = []
            curr = root
            while stack or curr:
                if curr:
                    sol.append(curr.val)
                    stack.append(curr.right)
                    curr = curr.left
                else:
                    curr = stack.pop()
            return sol
            
        def postorderTraversal(self, root):    # 后序遍历
            stack = []
            sol = []
            curr = root
            while stack or curr:
                if curr:
                    sol.append(curr.val)
                    stack.append(curr.left)
                    curr = curr.right
                else:
                    curr = stack.pop()
            return sol[::-1]
    

    1.4树的链表化

    <table>
        <tr>
            <td ><center><img src="https://img-blog.csdnimg.cn/20190511112024837.png" >输入 </center></td>
            <td ><center><img src="https://img-blog.csdnimg.cn/20190511112042474.png" >输出</center></td>
        </tr>
    

    思路:对于每一颗子树进行后序遍历,将右子树连接到左子树的右子树上,将左子树连接到根节点的右子树上;递归进行遍历

    # Definition for a binary tree node.
    # class TreeNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
     
    class Solution(object):
        def flatten(self, root):
            if root == None:
                return None 
            self.flatten(root.left)
            self.flatten(root.right)
            if root.left != None:
                p = root.left
                while p.right != None:
                    p = p.right
                p.right = root.right
                root.right = root.left
                root.left = None
    

    1.5给一个初始饮料瓶数,三个空瓶换一瓶,可以赊一瓶,求最后能喝几瓶

    def changeWater(cout_0):
        # 喝水的瓶数
        cout_1=0
        if cout_0<2:
            return 0
        while cout_0>2:
            cout_1+=cout_0//3
            cout_0=cout_0//3+cout_0%3
        if cout_0==2:
            cout_1+=1
        return cout_1
    

    1.6岛屿最大面积问题

    一个二维的01矩阵,上下左右都是1时算联通,求1组成岛的最大面积。
    思路:递归思想,若发现某一位置的数为1,则它周围上下左右都要递归,但是!!!此处递归时需要注意的是,每找到一个位置的数为1时,就要把这个位置的数变为0,否则会进入死循环。

    def max_area_of_island(grid):
        if not grid:
            return 0
        l, h = len(grid), len(grid[0])
        
        def dfs(i, j):
            if 0 <= i < l and 0 <= j < h and grid[i][j]:
                grid[i][j] = 0      #每找到一个位置的数为1时,就要把这个位置的数变为0
                return 1 + dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1)
            return 0
            
         #1)通俗写法
         for i in range(lenr):
                for j in range(lenc):
                    if grid[i][j] == 1:
                        count = dfs(i,j)
                        result = max(result,count)
         return result
    
    	#2)精简写法
    	result = [dfs(i, j) for i in range(l) for j in range(h) if grid[i][j]]
        return max(result) if result else 0
    

    1.7自己面试手撕的5道算法题

    看面经人家两轮技术面手撕两道算法题,到我这…手撕了5道…大概…也许…因为我不是科班出身???
    一面(45min):
    首先四道算法题,选一道15分钟写完,时间紧迫我选了第一道,给一个列表,求最大连续子序列和问题。
    然后笔试题复盘,字符串反转问题改进版,("hello world"变成"world hello"的复杂版,只不过会有些字符干扰,需要判断删除。)
    二面(1h):
    给一个n数,返回列表,比如n = 13,输出值[1,10,11,12,13,2,3,4,5,6,7,8,9],0<n<50000;
    链表反转;
    给一个链表,遍历一次,找出倒数第k个节点(这个只说思路,不用手写代码了)

    2.剑指offer

    2.1 数字中重复的数字

    思路1:建立一个同等大小的空数组,原数组的值为新数组的下标,访问一次置1,再次访问直接返回该值。
    思路2:若当前值的hash值已经加过1了,则直接返回。

    //思路1
    int findRepeatNumber(int* nums, int numsSize){
        int* arr = calloc(numsSize,sizeof(int)); //函数calloc()会将所分配的内存空间中的每一位都初始化为零
    
        for (int i=0; i< numsSize; i++){
            if (0 == arr[nums[i]]){
                arr[nums[i]] = 1;
            }
            else{
                return nums[i];
            }
        }
        return -1;
    }
    
    
    //思路2:
    int findRepeatNumber(int* nums, int numsSize){
        int *hash = (int *)calloc(numsSize, sizeof(int));
        for(int i = 0; i < numsSize; i++){
            if(hash[nums[i]] == 1){
                return nums[i];
            } else {
                hash[nums[i]]++;
            }
        }
        return -1;
    }
    

    2.1 二维数组中的查找

    def Find(target, array):       # array 二维列表
        if array == [[]]:
            return False
        m = len(array)  # m行n列
        n = len(array[0])
        i = 0
        j = n - 1
        while i < m or j >= 0:
            if target == array[i][j]:    #从右上角遍历
                return True
            elif target > array[i][j]:  # 右上角小于此数,删除行;否则删除列
                i += 1
                if i >= m:
                    return False
            else:
                j -= 1
                if j < 0:
                    return False
    

    c语言实现:

    bool findNumberIn2DArray(int** matrix, int matrixSize, int* matrixColSize, int target){
        // printf("%d\n",*matrixColSize);
        int m = 0, n = *matrixColSize -1 ; //注意带*,否则表示的是地址。
        if (matrixSize==0 && *matrixColSize ==0){
            return false;
        }
        while(m < matrixSize && n >=0){
            if (matrix[m][n] == target){
                return true;
            }
            else if(matrix[m][n] > target){
                n--;
            }   
            else{
                m++;
            }
    
        }
        return false;
    

    2.2 替换空格

    问题:请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

     def replaceSpace(s):
         li = []
         tmp = ""
         for item in s:
             if item!= " ":
                 tmp +=  item
             else:
                 li.append(tmp)
                 li.append("%20")
                 tmp = ""
         li.append(tmp)
         result = "".join(li)
         return result
    

    c语言实现:

    char* replaceSpace(char* s){
        int l = strlen(s),i = 0,j = 0;
        char *s_n = calloc(3*l+1,sizeof(char)); //申请动态内存,所以用指针,指向地址
        //3*l+1 是考虑最差的情况,倘若字符串都是空格,则是3倍,且还要考虑到结束符'\0'
        while(s[i]!= '\0'){
            if (s[i]!= ' '){ //用单引号,不是双引号!!!
                s_n[j++] = s[i];
                i++;
            }
            else{
                // printf("%d",1);
                s_n[j++] = '%';
                s_n[j++] = '2';
                s_n[j++] = '0';
                i++;
            }
        }
        return s_n;
    
    }
    

    学习:
    1.calloc,malloc的区别
    函数malloc()和函数calloc()的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存曾经被分配过,则其中可能遗留有各种各样的数据。
    函数calloc()会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那麽这些元素将保证会被初始 化为0;如果你是为指针类型的元素分配内存,那麽这些元素通常会被初始化为空指针;如果你为实型数据分配内存,则这些元素会被初始化为浮点型的零。

    2.strlen(s)计算字符串长度

    2.3 从尾到头打印链表

    问题:输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

    def printListFromTailToHead(listNode):
        tmp = []
        while listNode:
            tmp.append(listNode.val)
            listNode = listNode.next
        tmp.reverse()
        return tmp
    

    c语言:

    //思路1:先将链表反转,再逐个打印各个节点。该算法时间复杂度为O(N)。
    int* reversePrint(struct ListNode* head, int* returnSize){
        if(head==0){
            *returnSize=0;
            return 0;
        }
        struct ListNode*tmp,*header=head;
        int length=1,i;
        while(head->next!=0){
            length++;
            tmp=head->next;
            head->next=tmp->next;
            tmp->next=header;
            header=tmp;
        }
        *returnSize=length;
        int *res=malloc(length*sizeof(int));
        for(i=0;i<length;i++){
            res[i]=header->val;
            header=header->next;
        }
        return res;
    }
    
    //思路2:用一个数组反向存储链表节点。
    int* reversePrint(struct ListNode* head, int* returnSize){
        struct ListNode* p=head;
        int * a=(int*)malloc(sizeof(int)*10000);  //malloc的使用,分配动态内存,定义为指针的形式!!
        int n=0;//计算出链表大小
        while(p!=NULL){
            n++;
            p=p->next;
        }
        *returnSize=n;
        p=head;
        while(n--){ //用一个数组反向存储链表节点。
            a[n]=p->val;
            p=p->next;
        }
        return a;
    }
    

    学习:
    1.链表的表示

    2.4 重建二叉树

    在这里插入图片描述

    class Solution:
        def reConstructBinaryTree(self, pre, tin):
            # write code here
            if pre == [] or tin == []:
                return None
            root = TreeNode(pre[0])
            tmp = pre.pop(0)
            index = tin.index(tmp)
            
            left = tin[:index]
            right = tin[index+1:]
            root.left = self.reConstructBinaryTree(pre[:len(left)],left)
            root.right = self.reConstructBinaryTree(pre[len(left):],right)
            return root
    

    c语言解法:

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     struct TreeNode *left;
     *     struct TreeNode *right;
     * };
     */
    
    struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
        if(preorderSize==0) {
            return NULL;
        }
        int all,num=preorderSize; //标记先序数组第一个元素在中序数组位置
        struct TreeNode* node=malloc(sizeof(struct TreeNode));  
        
        node->val=preorder[0];
        while(num--) {
            if(inorder[num]==preorder[0]){  匹配preorder[0]在inorder的下标
                break;
                } 
        }
        
        all=num+1;
        node->left=buildTree(preorder+1,num,inorder,num); //数组名preorder表示其首地址preorder[0],加1表示preorder[1]  另外:没有struct TreeNode*前缀!!!!
        node->right=buildTree(preorder+all,preorderSize-all,inorder+all,inorderSize-all);
        return node;
    
    }
    

    学习:
    1.用结构体表示一个树;
    2.数组名表示其首地址。
    3.递归的实现。

    2.5用两个栈实现队列

    class Solution:
        stack1 = []    #定义两个栈为类属性
        stack2 = []
        def push(self, node):     #stack1用来实现append操作
            self.stack1.append(node)    
        def pop(self):
            if self.stack2 == []:    #stack1用来实现pop操作
                while self.stack1:
                    self.stack2.append(self.stack1.pop())
            return self.stack2.pop()
    

    C语言

    typedef struct {
        int len;
        int top1;
        int top2;
        int *s1;//栈1,入栈=入队
        int *s2;//栈2,出栈=出队
    } CQueue;    //定义一个队列
    
    
    CQueue* cQueueCreate() {
        CQueue *queue = malloc(sizeof(CQueue));   //结构体定义时别忘记*号
        queue->len = 10000;
        queue->top1 = -1;
        queue->top2 = -1;
        queue->s1 = malloc(queue->len * sizeof(int));
        queue->s2 = malloc(queue->len * sizeof(int));
        return queue;
    }
    
    void cQueueAppendTail(CQueue* obj, int value) {
        if(obj->top1 == -1)
            while(obj->top2 != -1)  //s2要空,将s1填满后,再添加新数。
                obj->s1[++(obj->top1)] = obj->s2[obj->top2--];
        obj->s1[++(obj->top1)] = value;
    }
    
    int cQueueDeleteHead(CQueue* obj) {
        if(obj->top2 == -1)
            while(obj->top1 != -1)  //s1要抽空,填入到s2中后,再删除s2的末尾
                obj->s2[++(obj->top2)] = obj->s1[obj->top1--];
        return obj->top2==-1 ? -1 : obj->s2[obj->top2--];
    }
    
    void cQueueFree(CQueue* obj) {  
        free(obj->s1);
        free(obj->s2);
        free(obj);
    }
    

    学习:
    1.typedef 重新定义结构体的名字为CQueue
    2.i++和++i 的区别。++i是自加完后在进行下一步计算,i++是先用i计算完后,再进行自加。
    3.free()释放动态内存

    2.6旋转数组的最小数

    问题:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
    思路:采用二分法,时间复杂度为logn

    def minNumberInRotateArray(rotateArray):
            if len(rotateArray) == 0:
                return 0
            left = 0
            right = len(rotateArray)-1
            while left < right:
                mid = int((left+right)/2)
                if rotateArray[mid] > rotateArray[right]:     #最小值在右边   5>2
                    left = mid+1
                elif rotateArray[mid] < rotateArray[right]:     #最小值在右边
                    right = mid
                else:                                        
                    right -= 1                #right-left=1的情况,right-1跳出循环
            return rotateArray[left]
    

    c语言----------二分法:分三种情况。
    1)首中末位相同,则首尾分别+1 -1。 比如 2 1 2 2 2 2,则减少数组至 1 2 2 2
    2)中间项大于最右项,则说明最小的数在中间项与最右项的里面。比如 3 4 5 1 2,中间项5,最右项 2,则在1里面找。
    3)中间项小于等于最右项,则说明最小数在最左项与中间项里面找。比如 3 1 3 3 3,最左项3,中间项3,最右项3,则在最左项与中间项之间找到。

    int minArray(int* numbers, int numbersSize){
        int left = 0; int right = numbersSize - 1;
        while(left < right){
            int mid = (left + right) / 2;
            if((numbers[mid] == numbers[left] && numbers[mid] == numbers[right])){
                left += 1;
                right -= 1;
            }else if(numbers[mid] > numbers[right]){
                left = mid + 1;
            }else if(numbers[mid] <= numbers[right]){
                right = mid;
            }
        }
        return numbers[left];
    }
    

    学习:二分法的思想

    2.7斐波那契数列

    思想:动态规划

    def Fibonacci(n):
            dp = []
            if n<2:    #n=0/1特殊情况讨论
                return n
            else:
            dp = [0,1]
            for i in range(2,n+1):   #求得是第n项,而第0项为0
                    dp.append(dp[i-2]+dp[i-1])
            return dp[-1]
    

    C语言

    int fib(int n){
        if(n==0){return 0;}
        if(n==1){return 1;}
    
        int *arr = malloc(101*sizeof(int));
        arr[0] = 0;
        arr[1] = 1;
        if (n>=2){
            for (int i =2; i<=n;i++){
                arr[i] = (arr[i-1] + arr[i-2]) % 1000000007;  //取模==取余
            }
        }
        return arr[n];
    }
    

    2.8 跳台阶

    2.7的变题

    def jumpFloor(number):
            if number < 3:
                return number
            else:               #其实有没有else都不影响,只不过有了更好理解。
                dp = [0,1,2]
                for i in range(3,number+1):
                    dp.append(dp[i-1]+dp[i-2])
            return dp[-1]
    

    c语言

    int numWays(int n){
        
        if(n==0){return 1;}
        if(n==1){return 1;}
    
        int* dp = malloc(101*sizeof(int));
        dp[0] = 1;
        dp[1] = 1;
        for (int i=2; i<=n;i++){
            dp[i] = (dp[i-1]+dp[i-2]) %1000000007;
        }
        
        return dp[n];
    }
    

    2.8 变题:变态跳台阶

    def jumpFloorII(number):
        if number < 3:
            return number
        dp = [0,1,2]
        for i in range(3,number+1):
            dp.append(sum(dp)+1)
        return dp[-1]
    

    2.9 矩形覆盖

    原理同2.7,实现代码都一样的。
    解题思路:
    当n=1时,记作F(1), 共有1种方法;
    当n=2时,记作F(2), 共有两种方法;
    当n=3时,记作F(3), 分为两种情况:
    第一次用一个矩形竖着覆盖(左图蓝色),则剩下共有F(n-1)种方法,即F(2) 种方法;
    第一次用一个矩形横着覆盖(右图蓝色),则剩下绿色区域只能有图示一种方法,那么剩下F(n-2)种方法,即F(1) 种方法;
    在这里插入图片描述

    def rectCover(number):
            if number < 3:
                return number
            dp = [0,1,2]
            for i in range(3,number+1):
                dp.append(dp[i-1]+dp[i-2])
            return dp[-1]
    

    2.10二进制中1的个数

    def NumberOf1(self, n):
            # write code here
            count = 0
            while n&0xffffffff !=0:   #这一行不能用while n:代替,运行会超时!!!
                n = n&(n-1)
                count +=1
            return count
    

    c语言
    思路:https://blog.csdn.net/u014801432/article/details/81286735

    int hammingWeight(uint32_t n) {
        int count = 0;
        while(n!=0){
            n = n & (n-1);     //核心!!!
            count ++;
        }
        return count;
    }
    

    2.11数值的整数次方

    def Power(base, exponent):
        if exponent == 0:    #递归边界条件
            return 1
        elif exponent == 1:
            return base
        elif exponent == -1:
            return 1 / base
    
        if abs(exponent) % 2 == 0:    #递归+二分法,减少运行次数
            result = Power(base, abs(exponent) // 2)
            result *= result
        else:
            result = Power(base, abs(exponent) // 2)
            result *= result
            result *= base
        if exponent < 0:
            result = 1 / result
        return result
    

    c语言

    //自己版本1:
    double myPow(double x, int n){
        long  num ;  //定义为long
        double result;
        if(n==0){return 1;}
        if(n==1){return x;}
        if(n==-1){return 1/x;}
    
        // printf("%d%d\n",n,-n);
        if(n < 0){
            num = n;
            num = -num;}    //注意!!!num = -n 就报错,超出int长度
        else{num = n;}
    
        if (num%2==0){
            result = myPow(x,num/2);
            result *= result;
        }
        else{
            result = myPow(x,num/2);
            result *= result;
            result *= x;
        }
    
        if (n<0){result = 1/result;}
        return result;
    }
    
    //简易版本2:
    double myPow(double x, int n) {
        if (0 == n) {
            return 1;
        }
    
        if (n < 0) {
            return 1 / (x * myPow(x, -(n + 1)));
        }
    
        if (0 == (n & 1)) {
            //判断为偶数
            return myPow(x * x, n / 2);
        } else {
            //奇数
            return x * myPow(x * x, (n - 1) / 2);
        }
    }
    
    

    注意:
    1.num 设计为long类型,因为n取负数,-n会超出int限制。

    2.12 打印从1到最大的n位数

    int* printNumbers(int n, int* returnSize){
        int nums = 0;
        for (int i =0; i<n; i++){
            nums  += 9*pow(10,i);
        }
        int* arr = (int*)malloc((nums+1)*sizeof(int));
        for (int j = 0; j<=nums;j++){
            arr[j] = j+1;
        }
        *returnSize = nums;
        return arr;
    
    }
    

    2.13删除链表中的节点

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     struct ListNode *next;
     * };
     */
     
    struct ListNode* deleteNode(struct ListNode* head, int val){
        if(head == NULL ){return head;}
        if(head->val == val){return head->next;}
    
        struct ListNode* tmp = head;
        while(tmp->next!= NULL){
            if (tmp->next->val == val){
                tmp->next = tmp->next->next;
            }
            else{tmp = tmp->next;}
        }
        return head; //指针指的向地址,tmp变,head也变
    
    }
    

    2.14正则表达式匹配

    递归思路:(简单化假设字符串中只有一个‘’)
    “mississpp”
    “misissp.”
    1、如果模式字符串p为空,那么代表已经匹配完毕,则字符串s也必须为空,作为递归的出口。
    2、由于模式中‘’和之前的一个字符有关,所以我们在递归新的p时得判断p中的第二个字符是否为‘’,若为‘*’:

    新字符串"ssisspp"
    “sissp.”
    判断s[0]是否和p[2]一致,若一致则代表部分已经判断完毕,后边继续判断,不一致,代表个数尚未判断完毕,则s+1作为新的s继续递归,
    直至判断到新字符串"isspp"
    “sissp.”
    之后便是"isspp"
    “issp.”
    这时候我们知道*判断完了,新的字符串则开始继续判断,不一致返回0,一致返回1

    bool isMatch(char* s, char* p){
        if(*p == '\0')
        {
            if(*s == '\0') return true;
            else return false;
        } //递归出口
    
        if(*(p+1) == '*')
        {
            if(isMatch(s, p+2)) return true;
            if(*s != '\0' && (*s == *p || *p == '.') && isMatch(s+1, p)) return true;
        }//判断‘*’符号是否能匹配上
    
        if(*s != '\0' && (*s == *p || *p == '.') && isMatch(s+1, p+1)) return true; //判断正常字符和‘.’的逐一匹配
        else return false;
    
    }
    

    学习:
    1)递归思想(要有递归结束条件)
    2)字符串要用单引号!!!!
    3)p+1和(p+1)的区别

    2.15调整数组顺序使奇数位于偶数前面

    def reOrderArray(self, array):
            list1 = [item for item in array if item%2 == 1]
            list2 = [item for item in array if item%2 == 0]
            result = list1 + list2
            return result
    

    2.13 链表中倒数第K个节点

    # -*- coding:utf-8 -*-
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    def FindKthToTail(head, k):
        # write code here
        if head == None or k==0:  #特殊情况1:链表为空或者k=0
            return None
        root1 = head
        root2 = head
        i = 0
        while i < k-1:    #root1走到k-1步,第k步两个节点一同开始走
            i+=1
            if root1.next != None:   
                root1 = root1.next
            else:
                return None        #特殊情况2:链表长度不为K
        while root1.next != None:
            root1 = root1.next
            root2 = root2.next
        return root2
    

    2.14 反转链表

    def ReverseList(pHead):
            # write code here
            if pHead == None:
                return None
            new_head = None
            idencity = None
            while pHead:
                idencity = pHead.next
                pHead.next = new_head
                new_head = pHead
                pHead = idencity
            return new_head
    

    2.15 合并两个排序的链表

    思路:递归

    def Merge(pHead1, pHead2):
            if not pHead1:
                return pHead2
            if not pHead2:
                return  pHead1
            if pHead1.val <= pHead2.val:
                pHead1.next = self.Merge(pHead1.next, pHead2)
                return pHead1
            else:
                pHead2.next = self.Merge(pHead1, pHead2.next)
                return pHead2
    

    2.16 树的子结构

    分两步:1)树1中找到树2的根节点;2)找到之后,对比左右子树是否相等

    # -*- coding:utf-8 -*-
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    
    class Solution:
        def HasSubtree(self, pRoot1, pRoot2):
            if pRoot1 == None or pRoot2 == None:
                return False
            return self.issubtree(pRoot1, pRoot2)
        
        def issubtree(self,pRoot1, pRoot2):
            if pRoot2 == None:   #pRoot2先遍历完则是
                return True
            if pRoot1 == None:   #pRoot1先遍历完则不是
                return False
            if pRoot1 == None and pRoot2 == None:   #同时遍历完也是子树
                return True
            res = False
            if pRoot1.val == pRoot2.val:  #查找该节点的左右节点是否相等
                res = self.issubtree(pRoot1.left, pRoot2.left) and self.issubtree(pRoot1.right, pRoot2.right)  
            #如果res为True,返回True,否则继续从左节点开始查找,如果还失败,从右节点开始查找
            return res or self.issubtree(pRoot1.left, pRoot2) or self.issubtree(pRoot1.right, pRoot2)
    

    2.17 二叉树的镜像

    # -*- coding:utf-8 -*-
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    class Solution:
        # 返回镜像树的根节点
        def Mirror(self, root):
            # write code here
            if root == None:
                return None
            root.left,root.right = root.right,root.left
            self.Mirror(root.left)
            self.Mirror(root.right)
            return root
    

    2.18 顺时针打印矩阵

    问题:
    在这里插入图片描述

    def printMatrix(matrix):
            res = []
            while matrix:
                res += matrix.pop(0)   #将matrix[0][:]即第一行pop出来,放入res中,此时matrix(3*4)
                if matrix and matrix[0]:    #matrix[:][-1]即最后一列pop出来,接着放入res中,此时matrix(3*3)
                    for row in matrix:
                        res.append(row.pop())
                if matrix:
                    res += matrix.pop()[::-1]    #将matrix最后一行pop出来,列表[::-1]倒叙读数,此时matrix(2*3)
                if matrix and matrix[0]:         #matrix[:][0]即第一列pop出来,倒叙接着放入res中,此时matrix(2*2)
                    for row in matrix[::-1]:     
                        res.append(row.pop(0))
            return res
    

    2.19 包含min函数的栈

    思路:设置一个变量存放最小值,每一次压栈的时候进行比较。再设置一个辅助栈,用于存放当前栈的最小值(设置辅助栈是因为,若最小值出栈了,最小值需要进行更新,因此需要辅助栈来保存次小值)

    class Solution:
        def __init__(self):
            self.stack = []
            self.minstack = []
            self.minm = float('inf')
        def push(self, node):    #push和pop都不用return,属于自操作
            if node < self.minm:
                self.minm = node
                self.minstack.append(self.minm)
            self.stack.append(node)
        def pop(self):
            if self.stack != []:
                if self.stack[-1] == self.minm:
                    self.minstack.pop()
                self.stack.pop(-1)
        def top(self):
            if self.stack != []:
                return self.stack[-1]
            else:
                return None
        def min(self):
            return self.minstack[-1]
    

    2.20栈的压入弹出序列

    思路:用一个栈和一个队列来模拟,如果栈顶和队列头部元素相同,同时pop掉,若最后栈是空的代表对

    def IsPopOrder(self, pushV, popV):
            stack= []     #定义一个栈
            while popV:
                if stack and stack[-1] == popV[0]:  #popV好比一个队列,与栈顶相同则pop
                    popV.pop(0)
                    stack.pop()
                elif pushV:    #模拟入栈,与上面的顺序不能乱
                    stack.append(pushV.pop(0))
                else:
                    return False
            return True
    

    2.21 从上往下打印二叉树

    问题:从上往下打印出二叉树的每个节点,同层节点从左至右打印。
    思路:用队列,每次放节点时,把他的左右子树也放到尾部

    def PrintFromTopToBottom(self, root):
            result = []
            queue = []
            if root == None:
                return result
            
            queue.append(root)   #储存的是节点而不是数值
            while queue:
                tmp = queue.pop(0)
                result.append(tmp.val)
                if tmp.left:
                    queue.append(tmp.left)
                if tmp.right:
                    queue.append(tmp.right)
            return result
                
    

    2.22 二叉搜索树的后序遍历结果

    思路:二叉排序树按照“左-右-根”的顺序遍历得到的序列具有这样的特点:该序列从中间分开,左边序列的值都小于序列的最后一个值,右边序列的值都大于序列的最后一个值。很明显,序列的最后一个值就是根节点,而这个分界点就是左右子树的分界点,因此,我们按顺序遍历这个序列,找到第一个大于根节点的值,就区分出了左右子树,同时,如果这个点左边的值大于根节点的值或者该点右边的值小于根节点的值,则说明此序列不符合要求,如果符合要求,则继续对左右子树按照上面的过程进行判断,明显这是个需要用递归解决的问题。

    #法一:循环 *****
    def VerifySquenceOfBST(sequence):
            if len(sequence) == 0:
                return False
            length = len(sequence) - 1
            i = 0
            while length != 0:
                while sequence[i] < sequence[length]:
                    i += 1
                while sequence[i] > sequence[length]:
                    i += 1
                if i < length:
                    return False
                length -= 1
                i = 0
            return True
    
    #法二:递归
    class Solution:
        #判断序列是否是二叉排序树的后续遍历序列    
        def VerifySquenceOfBST(self, sequence):
            if len(sequence)==0:
                return False
            if len(sequence)==1:
                return True
            root=sequence[-1]#根节点的值
            border=len(sequence)-1#必须初始化边界点的值,因为有可能没有右子树,就无法按照第一个大于root的方法找到border
            for i in range(len(sequence)-1):    #找出左右子树的分界处
                if sequence[i]>root: 
                    border=i
                    break
            for i in range(len(sequence)-1):  #判断左右子树是否都满足条件---边界点左边的值小于root,右边的值大于root
                if sequence[i]<root and i>border:
                    return False
                if sequence[i]>root and i<border:
                    return False
            if border==len(sequence)-1 or  border==0:#没有左子树或没有右子树
                return self.VerifySquenceOfBST(sequence[:-1])
            else:
                return (self.VerifySquenceOfBST(sequence[:border]) and self.VerifySquenceOfBST(sequence[border:len(sequence)-1]))
    

    2.23 二叉树中和为某一值的路径

    思路:
    首先要理解题意,是从根节点往子节点连。如果只有根节点或者找到叶子节点,我们就把其对应的val值返回如果不是叶子节点,我们分别对根节点的左子树、右子树进行递归,直到找到叶子结点。然后遍历把叶子结点和父节点对应的val组成的序列返回上一层;如果没找到路径,其实也返回了序列,只不过是[]。

    def FindPath(self, root, expectNumber):
            if not root:
                return []
            if root and not root.left and not root.right and root.val==expectNumber:   #没有左右节点,且此节点值为目标值
                return [[root.val]]
            res = []
            left = self.FindPath(root.left,expectNumber-root.val)
            right = self.FindPath(root.right,expectNumber-root.val)
            for i in left+right:
                res.append([root.val]+i)    #递归时减去的当前节点值此时要加上
            return res
    

    2.24 复杂链表的复制

    思路2:将原链表和新链表各节点地址做字典存储下来。

    # class RandomListNode:
    #     def __init__(self, x):
    #         self.label = x
    #         self.next = None
    #         self.random = None
    
    #法一:
    def Clone( head):
        if not head: return
        newNode = RandomListNode(head.label)
        newNode.random = head.random
        newNode.next = self.Clone(head.next)
        return newNode
    
    #法二:
    def Clone(pHead):
            newhead = RandomListNode(0)
            dic = {}
            temp = pHead
            new = newhead  # 这两个变量的目的在于:newhead,pHead遍历到尾部节点时,这两个指针还在头节点,又等价于newhead,pHead(因为浅拷贝)
            
            while pHead:  #步骤1-----正序节点赋值
                newhead.next = RandomListNode(pHead.label)
                dic[pHead] = newhead.next  # 之所以是next,是因为newhead初始化是头节点为0
                pHead = pHead.next
                newhead = newhead.next
            new = new.next
            n = new  # 同定义newhead,pHead的目的一样,备份表头
            
            while temp:  # 步骤2----随机节点复制
                if temp.random:
                    new.random = dic[temp.random]
                temp = temp.next
                new = new.next
            return n
    

    2.25 二叉搜索树与双向链表

    思路:二叉搜索树是有序的,只要中序遍历,就是一个从小到大有序的序列。
    1).双向链表表头一定是最左的节点
    2). 表尾不断以中序遍历方式向右移动:

    class Solution:
        def __init__(self):
            self.listHead = None     #头节点备份
            self.listTail = None     #搜索二叉树变成双向链表,指针遍历
        def Convert(self, pRootOfTree):
            if pRootOfTree==None:         #递归终止条件
                return
            self.Convert(pRootOfTree.left)     #中序遍历是顺序序列
            if self.listHead==None:              #初始化链表头节点
                self.listHead = pRootOfTree
                self.listTail = pRootOfTree
            else:
                self.listTail.right = pRootOfTree     #搜索二叉树变成双向链表
                pRootOfTree.left = self.listTail
                self.listTail = pRootOfTree
            self.Convert(pRootOfTree.right)
            return self.listHead
    

    2.26 字符串的排序 (思路有些绕)

    思路:递归法,问题转换为先固定第一个字符(首位可能是a/b/c),求剩余字符的排列;求剩余字符排列时跟原问题一样。
    (1) 遍历出所有可能出现在第一个位置的字符(即:依次将第一个字符同后面所有字符交换);
    (2) 固定第一个字符,求后面字符的排列(即:在第1步的遍历过程中,插入递归进行实现)。

    class Solution:
        def Permutation(self, ss):
            if len(ss) <=0:
                return []
            res = list()     #创建一个空列表,res = []
            self.perm(ss,res,'')
            uniq = list(set(res))
            return sorted(uniq)
        
        def perm(self,ss,res,path):
            if ss=='':    #临界条件
                res.append(path)
            else:
                for i in range(len(ss)):
                	#print(ss[:i] + ss[i + 1:], res, path + ss[i])	
                    self.perm(ss[:i]+ss[i+1:],res,path+ss[i])          #********核心思想!!!
    
    #训练过程:
    """
    bc [] a        i=0   因为传入的ss在变,所以里面还有小递归
    c [] ab
     [] abc
    b ['abc'] ac  
     ['abc'] acb
    ac ['abc', 'acb'] b      i=1
    c ['abc', 'acb'] ba
     ['abc', 'acb'] bac
    a ['abc', 'acb', 'bac'] bc    
     ['abc', 'acb', 'bac'] bca
    ab ['abc', 'acb', 'bac', 'bca'] c     i=2
    b ['abc', 'acb', 'bac', 'bca'] ca
     ['abc', 'acb', 'bac', 'bca'] cab
    a ['abc', 'acb', 'bac', 'bca', 'cab'] cb
     ['abc', 'acb', 'bac', 'bca', 'cab'] cba
    """
    

    2.27 数组中出现次数超过一半的数字

    思路1:排序之后,中间的数就是答案,但是时间复杂度是 nlogn
    思路2 :时间复杂度n的方法:初始化一个count ,flag设置为数组第一个,如果碰到相同的+1,否则-1,当减到0时候更换result为当前的,count归为1,最后记得验证一下。(原理–如果元素次数大于数组一半时,相同加1到最后的计数必然大于0)

    def MoreThanHalfNum_Solution( numbers):
            flag = numbers[0]      
            count = 1
            if len(numbers) == 0:
                return 0
            for i in range(1,len(numbers)):
                if numbers[i] == flag:
                    count +=1
                else:
                    count -=1
                    if count < 0:
                        count = 1
                        flag = numbers[i]
            
            #上述结果可能不对,需要验证次数是否超过数组长度的一半
            count = 0
            for num in numbers:
                if num==flag:
                    count +=1      
            if count>len(numbers)//2:
                return flag 
            else:
                return 0
    

    2.28 最小的K个数

    利用堆排序,适合处理TOP-K问题
    (1)遍历输入数组,将前k个数插入到推中(定义为最大堆);(利用heapq模块来做为堆的实现)
    (2)继续从输入数组中读入元素做为待插入整数,并将它与堆中最大值(堆顶的值)比较:
    如果待插入的值比当前已有的最大值小,则用这个数替换当前已有的最大值;
    如果待插入的值比当前已有的最大值还大,则抛弃这个数,继续读下一个数。
    这样动态维护堆中这k个数,以保证它只储存输入数组中的前k个最小的数,最后输出堆即可。这种方法只需要开辟一个长度为k的空间,大大节省了空间的消耗

    import heapq    # 利用python的heapq模块,来实现堆的操作
    class Solution:
        def GetLeastNumbers_Solution(self, tinput, k):
            # write code here
            maxheap = []
            if k <= 0 or tinput == None or len(tinput)<k:
                return []
            for i in range(k):
                heapq.heappush(maxheap,-tinput[i])    #python自带的heapq模块实现的是最小堆,没有提供最大堆的实现,所以取反为负值
            for i in range(k,len(tinput)):
                if maxheap[0]> -tinput[i]:
                    continue
                else:
                    heapq.heappushpop(maxheap,-tinput[i])    #heappushpop(a,x)在弹出最小值之前将x推送到a上
                    
            result = []
            for i in range(k):
                result.insert(0,-heapq.heappop(maxheap))     #一个个弹出堆顶端元素,并保存到列表中
            return result
    

    2.29 连续子数组的最大和

    思想:动态规划

    def FindGreatestSumOfSubArray(array):
            dp = [array[0]]    #初始化第一个位置
            for i in range(1, len(array)):
                dp.append(max(dp[i-1] + array[i] , array[i]))
            return max(dp)
    

    2.30 整数中1出现的次数

    def NumberOf1Between1AndN_Solution(self, n):
            count = 0
            for i in range(n+1):
                s = str(i)
                if "1" in s:
                    count += s.count("1")
            return count
    

    2.31 把数组排成最小的数

    python2专用的用cmp

    def PrintMinNumber(self, numbers):
            if not numbers:
                return ""
            lmb = lambda n1, n2:int(str(n1)+str(n2))-int(str(n2)+str(n1))
            array = sorted(numbers, cmp=lmb)      #python2专用,用cmp
            return ''.join([str(i) for i in array])
    

    2.32 丑数

    思路:
    首先从丑数的定义我们知道,一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那么我们从1开始乘以2,3,5,就得到2,3,5三个丑数,在从这三个丑数出发乘以2,3,5就得到4,6,10,6,9,15,10,15,25九个丑数,我们发现这种方法会得到重复的丑数,而且我们题目要求第N个丑数,这样的方法得到的丑数也是无序的。那么我们可以维护三个队列:

    def GetUglyNumber_Solution( index):
        if (index <= 0):
            return 0
        uglyList = [1]  # 丑数列表
        indexTwo = 0    #维护三个队列,这是其位置
        indexThree = 0
        indexFive = 0
        for i in range(index - 1):
            newUgly = min(uglyList[indexTwo] * 2, uglyList[indexThree] * 3, uglyList[indexFive] * 5)  
            uglyList.append(newUgly)
            if (newUgly % 2 == 0):   #丑数列表添加谁的倍数,把谁的index后移。
                indexTwo += 1
            if (newUgly % 3 == 0):
                indexThree += 1
            if (newUgly % 5 == 0):
                indexFive += 1
        return uglyList[-1]
    

    2.33 第一次只出现一次的字符串

    def FirstNotRepeatingChar(s):
            if not s:
                return -1
            for i,ch in enumerate(s):
                if s.count(ch)==1:
                    return i
    

    2.34 数组中的逆序对

    思想:归并排序

    2.35 两个链表的公共节点

    def FindFirstCommonNode(pHead1, pHead2):
            list1 = []        #用列表储存链表1的数值
            node1 = pHead1
            node2 = pHead2
            while node1:
                list1.append(node1.val)
                node1 = node1.next
            while node2:
                if node2.val in list1:
                    return node2
                else:
                    node2 = node2.next
    

    2.36 数字在排列数组中出现的次数

    def GetNumberOfK(data, k):
            return data.count(k)
    

    2.37 二叉树的深度

    # -*- coding:utf-8 -*-
    # class TreeNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.left = None
    #         self.right = None
    class Solution:
        def TreeDepth(self, pRoot):
            if pRoot == None:
                return 0
            lDepth = self.TreeDepth(pRoot.left)
            rDepth = self.TreeDepth(pRoot.right)
            return max(lDepth,rDepth)+1
    

    2.38 平衡二叉树

    展开全文
  • 下面是按照我的面试顺序进行排序的。 微软 微软是参加的进校面试,(师姐安利的,师姐是参加的夏令营)微软的面试体验是非常的棒的,微软特别尊重面试者,面试一般集中在问算法题上,一时想不出方法,面试官也会...

    目前不打算再投其他的公司了,所以来写面试总结。一直被各种人追问面经,准确写好一劳永逸哈哈哈。本人985硕士,性别女,可以参考下哈。有什么问题,可以留言哈。

    1.微软
    微软是参加的进校面试,(师姐安利的,师姐是参加的夏令营)微软的面试体验是非常的棒的,微软特别尊重面试者,面试一般集中在问算法题上,一时想不出方法,面试官也会给一些思路引导,不会怼人真的是很亲切的。。。

    进校面试是上午10点签到,10点到11点现场笔试,笔试为两道基础数据结构算法题,第一题为查找两个链表的公共节点,第二题为最大堆的插入节点与删除节点。要求在A4纸上手写代码实现,要注意判空和边界,以及算法复杂度和空间复杂度。微软看重算法的实现。

    11点到12点宣讲并公布笔试结果,中午休息下午进行面试。面试分三轮,一面与二面为平行面,两面中至少有一位面试官给通过才能进入第三轮面试。一面的面试是看了看简历,什么都没问简历相关的东西,直接出题。问,一个流数据流过来,要去读取这个数据,然后需要反复读一部分数据所以用buffer存储它,buffer里的数据可以反复读,但是buffer如果读完没有让读数据的指针指向之前的数据的话,指针就无法再回去读buffer的数据了,所以要实现如何让它再去读buffer的数据。(其实我完全没听懂啥意思)面试官给我解释了一下,但是我还是没怎么听懂到底想让我怎么实现。最后我只写出了每次调用指针定位数据就开始读数据,一直读到末尾。面试官说我没有实现如何把buffer读完之后,怎么再返回到buffer里面去读。。。(听不懂,心很累)然后,我感觉凉凉,便等待第二面。

    二面的面试官性格非常好,一开始看了看简历,让我介绍一下现在做的项目,我是尽全力再介绍了,不过他好像没怎么听懂。然后问tensorflow与pytorch的区别。然后就开始出题,一共两个题。第一个题目是,括号匹配,一个字符串中有左括号、右括号、星号,星号代表左括号或者右括号,判断是否是合理的括号匹配。(如果想让我写出问题答案或思路,请在评论中留言哈,这里就不说答案了)由于第一题回答的太快了,又有第二题目,是第一个字符串重复多少次可以包括第二个字符串。实现的时候都要注意判空与边界。然后面试官看了下时间,说还有一段时间(微软面试一般是1小时),就告诉我他这边肯定是过了,问我有什么想让我在评价中写的吗?我就大致说了说想做的东西,他说可以帮我在评论中写上我的意愿。很耐斯的面试官。

    然后,顺利进入三面。三面应该是主管级别的,首先自我介绍(不得不说,自我介绍是真的不知道怎么表现自己),然后让我描述一个简历中的项目,然后我又讲了一遍我最近的项目,感觉面试官也没怎么听懂。然后问我知不知道hadoop与spark的区别,用英文说一下。(微软都会有英文面试,当时教室里的人都在乌鲁乌鲁说英语),说完之后让用中文再说一遍。然后就再开始出题,题目是给定一个数组,求取其中的有最大和的子数组,简单DP。面试官提出了代码的几个问题,是空间复杂度的问题,时间复杂度要求是o(n),做到之后需要空间复杂度为o(1),当时是用数组存储的所以空间复杂度为o(n)。然后就让再改下,改出来之后便面试结束。面试官也很耐斯。
    然后,HR说回去等通知。

    一周过后,借到HR电话,说有会第四面skype视频面,面试时间为三天后。第四面应该是总监面,首先自我介绍,然后描述一个简历中的项目,项目中是怎么与人合作的。然后开始出题,将罗马数字转为阿拉伯数字。
    三天过后,给HR发邮件询问面试结果,说得到了面试官的Hire。一周过后,收到了HR的同意邮件,相当于口头offer,薪资会再商议。

    2.华为
    都说华为面试水,一开始我还不相信,后来真的信了。
    投的提前批,笔试三道题300分据说150就可以过,我做了260顺利收到面试通知。面试是在香格里拉酒店,环境是一级棒啊。一共两轮面试,一轮技术面,二轮综合面。

    一面面试官应该是做java的,我简历上一共两个java项目,就问这两个java项目了,由项目会引申出很多相关问题,例如写出匹配多个字符串的正则表达式、描述一个场景是怎么实验的,基本是在判断你的项目的真实性。最后面试官让写出,读入一个文件,判断里面有多少个’hello world’,语言不限。面试大概一个小时。
    二面等了两个小时才到我,都到了下午六点。。(是真的饿)二面也就十分钟,了解家庭情况,有没有男朋友,个人性格方面的问题。面试结束,面试官还最后跟我握手,挺耐斯的。
    一周后收到HR发的面试通过的短信,注明有 ‘并非正式offer’。

    3.网易
    3.1网易游戏(雷火伏羲实验室)
    投的伏羲AI实验室的人工智能工程师,笔试要去公司现场,面试也要去公司现场。。(公交车超累的。。)
    笔试感觉难度挺大,四张卷子,一张选择,半张填空,一张半简答,半张编程题(半张意思是一面)
    编程题是迷宫题,dfs解决。因为投的人工智能,选择填空和简答都是深度学习以及机器学习的知识,强化学习考察的偏多。可能他们游戏用强化学习比较多吧~
    笔试顺利通过,第二周收到面试邀请,问下周是否参加面试。

    面试还要去现场面,路途是真的奔波,网易游戏提供了高铁二等座的报销,面额不超过1200,同时通过笔试参加面试的人去签到即可获得小礼物一份,礼物为倩女幽魂挂链、小猪佩奇玩偶、网易游戏帆布包以及面试必过符(网易游戏是真的有钱~)
    面试为上午两面平行面,人工智能岗位对深度学习算法可能要求比较高,所有的算法都要在纸上可以画出思想,以及推出公式。我只能做到画出思想。。不过去伏羲AI实验室实习人工智能的同学说算法做的很少,都是搞平台开发的。

    第一面面试官比较耐斯,上来自我介绍,后问做的深度学习的项目用到的LSTM,画出原理图,以及写出推导公式,我当然推不出来。然后问的都是关于大数据的知识,因为我本身也有大数据的项目,Flume、Kafka、ES、Spark Streaming的原理以及各种使用方法都有问到。比如Flume是怎么配置的,用的哪种agent,介绍一下Flume里面的三个部件;Kafka的消息发送接收机制,Kafka的topic、partition的定义;ES的索引、以及与标准数据库的差别与对应之处;Spark Streaming的RDD有哪些细分,以及实现机制。然后问了些linux基础知识,文件的权限以及常用命令;还问了python的使用情况,元组与列表的区别,以及字典的使用。(这个时候我感觉我跟人工智能已经脱离了。。)
    最后一道算法题,一行一行的遍历树结构,要求五分钟内写出来(使用队列即可实现),面试结束,进行第二面。

    第二面面试的与第一面差不多,另外还涉及到了Kmeans算法原理,K的选择与初始点的选择;ES倒排索引的原理;以及图像中对抗学习的使用原理。最后一道算法题,深度遍历树结构(使用栈即可实现),面试结束。
    第一面与紧接着的第二面一共面了两个小时。中午可在食堂用餐,1点半公布结果(是否进入第三轮),网易食堂是免费,但感觉不怎么好吃哎(我是吃的盒饭类型的饭哈)。

    结果两点多才公布结果,大概三点半开始第三面,面试半小时。面试官上来就说要把我转到平台开发,问我可不可以接受。简单的问了所有的大数据的项目,每个组件用的什么版本(真的每个都问了是用的什么版本,也是神奇),大致了解下项目是怎么做的,结果面试。据说今年人工智能爆满,没人投开发岗。。所以开发岗很缺人的。
    招聘助理说一会有HR面试,要等下。

    大概四点半开始HR面试,面试半小时。首先自我介绍,之后问些性格问题,大致是了解团队合作怎么样,是否可以与人愉快的交往之类的。由于是第一次HR面试,完全不懂得套路,HR让我用两个词来形容自己,愣是没想出来。。。还要描述在项目中觉得自己有哪些缺点(???)有很多我都不知道怎么回答,可能回答的HR不是很满意吧。

    大概一周多的时间,招聘助理打来电话,接到了offer待处理的通知。

    3.2网易互联网(云音乐)
    (一面挂,羞耻呀)
    我投的算法工程师-NLP。笔试为在线笔试,20道选择,3道编程,2道简答。题目挺难的,很多同学都挂了。需要好好准备哦。

    大概过了几周收到面试通知,现场面试(又要去网易。。)网易互联网是公众号叫号。
    一面面试官一开始自我介绍,然后他看了下简历感觉极度凉凉,可能他只找到了一个小项目是他所涉猎的。开始提问LR原理,信息熵、信息增益、信息增益率,都要写出公式,我一个都不会写。。(抱歉我完全不想为了面试去记公式),只是口头说原理,感觉那个人爱答不理,也不怎么听我讲。然后让我写出合并两个有序链表的伪代码(注意是伪代码),然后写完,他说你这个有错误让我改,然后我改了。然后说我这个代码无法上线(???)。然后说面试结束,有什么想问的。我说NLP算法工程师主要做什么,他说什么kmeans、LR都在尝试,tensorflow也在尝试(???)。给我的感觉是网易云音乐的算法可能偏向于做推荐,其他的可能没怎么做新的东西。然后三分钟后收到不通过。

    再见,回到宿舍怒卸网易云音乐。(感觉网易云音乐今年极度不缺人,师兄师姐一面也挂了(前端))
    就这样,一面面试官那副嘴脸在我脑海里挥之不去(233没有这么严重哈,当时我阿里也只剩HR面了)

    4.阿里爸爸集团
    阿里是走的内推,内推岗位为算法工程师。是师姐帮忙找人内推的,部门隶属于阿里云。因为部门是做深度学习的,所以问题偏向于深度学习知识,不过问题都是根据简历问的,因人而异,仅供参考哈。

    内推第二天收到一面,一面为简历面,历时将近两个小时。首先,介绍最近做的深度学习的项目,面试官很耐斯,我在介绍的时候没有打断我的讲话,讲完之后面试官提问了些细节,大概有十五分钟,面试官已经明白我是怎么做的了。然后对项目的细节做出提问,比如特征是如何计算的,损失函数是用的什么,为什么使用这个模型,以及项目引用的论文思想。(其实问的很细的,就是每一步是怎么做的,我一时想不起来具体的问题)然后问还做过什么深度学习的项目。简历中也有大数据的项目,提问spark 与tensorflow分布式平台的区别,kmeans或者其他的算法是如何实现分布式,SVM的原理以及核函数的定义,(都是根据简历中提到的知识点进行提问,问题很多暂时回忆起这些)最后是在线编程,题目为K大数,要求算法复杂度为O(n),即为快速排序算法的变种。
    面试结束,一面面试官也是我的内推人,感觉我跟部门很match,讲了很多他们部门在做什么,面试官也非常厉害,海归博士一堆论文还是阿里星,羡慕!!

    一面第二天即收到二面,二面为主管面,首先,介绍最近做的深度学习的项目,面试官疯狂打断并疯狂问问题,就是问一些做的细节,到底是怎么做的,数据一开始怎么处理的,为什么用这个模型,你这样做创新点在哪里。然后进行对简历的技术点提问,有一个大数据项目面试官说偏工程就没怎么问,然后问LR的原理,LR与SVM的区别,hadoop的原理,hadoop与spark的区别;如果实现kmeans、LR、SVM算法,用hadoop和spark有什么区别,或者说用哪个更适用?Spark Streaming的原理(大概就是简历上写什么,基本上都会问这个的原理,说完原理可能还会深入问一个问题)
    最后向面试官提问,我是否还能接着面试,面试官笑着说应该可以。二面一小时。第二天内推人告诉我过了,准备三面吧。

    三面应该是总监面,全程被怼,怼到没朋友,经受了阿里传说中的压力面。。太痛苦了。。全程没有问技术(阿里好像都是这样,两面技术,三面不问技术问其他的,四面交叉,五面HR)首先问看你最近都在搞深度学习算法,有做过深度学习的项目吗(超轻蔑的,时间是周一的八点面的,感觉面试官有一种我极其耽误了他的睡眠时间的怒感)然后问你现在项目为什么选这个模型?参考别人思想,那你的思想在哪里?比如你现在面对一个别人从来没处理过的问题,你现在用什么模型都无法收敛怎么办?(我说调研一下都用什么模型,然后就疯狂被怼啊,说用啥都发散就问你怎么办??当时内心是崩溃的)问你是不是数学比较好,那你说L1L2正则项为什么加上之后对整个式子没有影响?(试图说L1L2原理,被疯狂怼,说不要听原理就问你为什么加上没有影响, oh no…各种朋友们,遇到这种面试官一定要坚强)然后在线编程,找到树中两个结点的最近公共父结点(递归即可解决),然后他一度怀疑我写的是最远公共子结点。然后然后又加了一题,用多线程实现定时器,每到一段时间就执行一个任务,并实现多种任务执行。
    面试结束,三面一小时。面完整个人是灰暗的。。。第二天意外得到通过惊喜,说还会有交叉面和HR面。三面给我的感觉是,无论面试官怎么怼,心态一定要放平,保持谦虚谨慎就好了,疯狂被怼大概是压力面吧。。(抱住pangpang的自己)

    四面交叉面,都说交叉面不挂人的,一开始我还不信,后来信了。交叉面一共15分钟,大致问了问最近项目怎么做的,为什么这么做。然后对简历上的技术点问了几个地方。比如tensorflow的优缺点,深度学习算法的优缺点,要结合平时使用。就迅速的挂了电话。

    五面HR面,交叉面和HR面是平行的,不分先后(意思是不是交叉面过了才有HR,是两个面试我都需要面)。HR小姐姐很耐斯,问问题也很有技巧,HR的技巧在于让你感到你是在和她聊天而不是面试,而她可以在聊天过程中判断你的各项性格。聊天过程还是很舒适的,没有第一次HR面试那么不知所措。。大概是先问对前面哪个面试官印象最深为什么;城市的选择为什么;最印象深刻的项目;与老师的关系;与父母的关系、性格与影响。最后讲了之后会有结果,最后要审核发放offer不能保证有offer(感到凉凉),也讲了入职的后续流程(感到有一些些希望),同时也告诉我可以多面几家,不要就面一两个就算了(这个让我感觉有一些些凉)。

    面试结束,面试时间半小时。轻松愉快。然后进入了焦急的等结果状态。功夫不负有心人,三天后收到了录用喜报(意向书),真是一把鼻涕一把泪,开心~ 因为我超希望进入这个部门,因为我现在做的实验,他们也在做,特别match。我也特别想知道阿里是如何做深度学习工程的。希望可以收到最后的offer!!!

    在收到offer之前,我还投了头条与搜狗,但是九月份投的太晚,至今没有通知。
    后续如有offer状态更新我会及时更上来,祝大家也有收到称心如意的offer~

    ----------------------------9.29更--------------------------------
    我拒绝了其他所有的笔试,前几天收到了微软说十一之前会发第一批offer,如果没有收到要等到十一之后再发,然而我至今米有收到。也收到了阿里巴巴的电话,问我什么时候可以签订三方,让我尽快签订。然饿还是没有正式offer,哇等的好着急。

    ----------------------------10.23更--------------------------------
    拿到网易游戏平台开发offer,薪资17k*13
    拿到阿里巴巴算法工程师offer,薪资20k*16
    ----------------------------11.7更----------------------------------
    拿到微软苏州软开工程师offer,薪资23w
    (微软所有offer都是软开,进入部门再细分,可以自己选择弹性比较大)
    拿到华为算法工程师offer,薪资20k,按照评级发14或16

    综上可以看出,只要面试通过的,收到意向书之后,offer都是稳的,没有传说中公司很不靠谱不发offer的情况,祝大家也收到自己喜欢还有钱途的工作哦,蟹蟹大家的关注,有任何问题都欢迎提出哦~
    最后,大家加油呦!!
    在这里插入图片描述
    ----------------------------完结 撒花----------------------------

    展开全文
  • 元旦更新:最后调成部门和岗位啦!...更新:9.30号收到短信和邮件的offer(所以那些刚面试完的童鞋不要着急,一般都要等一个月左右才发offer,官网查录用排序状态码那些其实也没啥用,方法可自行百度) 邮...

    元旦更新:最后调成部门和岗位啦!中央研究院蓝精灵实验室,估计是NLP或语音算法,据那位诺亚方舟的技术官跟我说,蓝精灵实验室做的事情和诺亚那边一样,蓝精灵更偏向工程实践,诺亚偏理论研究。打算去了,除非春招能找到更好的公司算法岗。

    更新:9.30号收到短信和邮件的offer(所以那些刚面试完的童鞋不要着急,一般都要等一个月左右才发offer,官网查录用排序状态码那些其实也没啥用,方法可自行百度) 邮件附带就业协议书签署,海外留学生通道都是两方,写死了薪水,只需要签个名字扫描发送即可完成签约。薪水不方便透露,只能告知算法岗14级劝退价。

    另外,华为最恶心的事情还是发生了,随机分配岗位!面试的算法,收到offer当天就有两个华为HR加我微信告诉我,被分配到中央软件院做云计算开发!死活不同意,目前申请调部门调回算法岗中,后事如何还不知道,微信问华为这些HR总是不理人。算了先签着,后面找到更好的offer再拒华为。

    PS:华为今年非常缺人,很多同学都收到并且拒了华为。另外华为留学生招聘的应届生年限是两年,而且华为每年3月8月12月 北上深都有海外招聘专场,所以悠着点找工作,祝大家好运 

    -------------------------------------------------------------------------------------------------------------------------------------------

    文中所提到的流程仅限于技术岗,非技术岗我不了解。

    2019华为校招8.16号上海海外专场 自然语言处理算法岗 面试已通过

    大概是7月底投的华为上海海外专场,官网投递,无内推,选的中央研究院,中央软件院。后来收到性格测试,再后来收到笔试,

    这里特别强调:性格测试,网上有题库和答案,搜一下就知道了,千万不要小看性格测试,很多人这个没通过,因为一般人觉得follow my heart就没问题,结果不是华为的菜,就挂了!
    当时在杭州海康威视实习着,离上海很近,加上我有个海外的学位,所以就参加了上海的海外专场,后来了解到其实这个专场也是上合地区的优招,因为好多海龟还在海外上课,没能来上海面试,所以充分利用资源也当做上合地区的优招了。

    面试通知如下图所示

    面试总共有两面:业务面试和综合面试,特别强调:技术岗没有英语测试,无!

    我两面都是问技术,一面半小时,二面一小时。总体是自己讲项目,讲实习,面试官会不时打断进行项目相关的提问,有时候会问的比较深。总体比bat面试水很多

    一面:我先介绍一下教育背景,以及研究生联合培养的课程啥的,时间都用来上课写作业了,不分配导师,无论文,无相关项目.....

    面试官主要问我在海康实习做的东西,让我手写java的接口,问我如果调用接口时候,传参数不完整怎么办,我答的不好,瞎说了一下,定义接口时候,里面定义结构体变量,面试官沉默而不语....面试官就问我实习是不是没写多少代码,呜呜,显然.....我实习做的东西有有些杂,一开始是做java后开开发,但是没过多久,项目需要又让我去做ElasticSearch分词器的研究(分词器就跟NLP相关,正合我意!)

    问完实习,我就讲项目,面试官貌似不懂机器学习,所以就没问我什么,基本是我讲。我跟他讲了讲C++内存泄漏及检测,他问了我手写数据库多表查询的语句,还有索引该怎么优化。还问了我快排。其他就没了。

    面试官面完,站起来对我说:“你的业务面试通过,请到旁边的综合面试等候”。那个时候听到这句话,我的内心无比欢喜!哈哈哈哈~

    二面:和一面一样从实习到项目到比赛到专利,一一讲,问我实习做的分词,倒排索引是什么,面试官问了集成学习xgboost adboost流程,决策树,CART,问我word2vec原理,我讲了一下wordembedding,负采样,问我jieba分词原理,还问熟悉什么NLP技术,我说softmax,lstm,但是只是看过,没实现过。问我深度学习RNN那些接触多少,我说没做过相关项目,只是跟教程运行了一下。二面聊了挺多,问我是否愿意做机器学习,我说都可以,毕竟NLP和机器学习很相关。最后问了性格优势弱势。跟我讲了讲中央研究院和中央软件院的区别,中央研究院是做未来五年的研究,70%的项目是会失败的,中央软件院是做未来三年的研究。我说都行,哪个要我我就去。最后问我为什么选择华为,我就画龙点睛的说了一句,“华为,大有可为!”哈哈哈哈哈,面试官也笑了233...因为这次招聘的口号就是 加入华为,大有可为...

    下面附上面试现场的图:

    排队刷身份证签到排号,手机会收到面试提醒的短信,现场还有面试叫号的显示屏,所以安排的井井有序,和腾讯的面试很像。

    就我所参加过的面试看来,华为这次现场面试的人并不多

    华为就是有钱,面试现场有非常多吃的东西,根本不用担心挨饿

    我面完一面,偷偷拍下了面试的现场场景,都是1V1,二面的场景也一模一样。

    二面聊完之后,还特意问是否有英语测试,面试官说没有,并说现场不会给出面试结果,说一周后通知结果。

    后来,面试结束后第二天就看到官网进度更新为下图

    面试完后第9天,收到短信和邮件,内容一样,如下图

    最后,感谢所有帮助过我的师兄师姐和雨神(没有他的神助攻,我笔试就挂了,呜呜),祝愿大家秋招顺利!

    最后,附上笔试的题目及代码,最后一题当时没做出来,事后也没去做了,求大佬来解答。

    笔试是三道编程题,题目及代码如下链接:

    //2019.8.1华为校招海外留学专场 题目一
    //找出输入字符串中的重复字符,再根据ascii把重复的字符从小到大排序
    //输入:一个长度不超过100的字符串,如:ABCABCdd
    //输出:排序后的字符串,如:ABCd
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Scanner;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Scanner;
    public class Main{
    public static void main(String[]args){
            Scanner scanner=new Scanner(System.in);
            String s=scanner.nextLine();
            char c[]=s.toCharArray();
            Map<Character,Integer>map=new HashMap<Character,Integer>();
            StringBuilder sb=new StringBuilder();
            for(int i=0;i<c.length;i++)
            {
                if(map.containsKey(c[i])){
                    int oldValue=map.get(c[i]);
                    map.put(c[i],++oldValue);

                }
                else{
                map.put(c[i],1);
                }
            }
                Iterator<Map.Entry<Character,Integer>>iterator =map.entrySet().iterator();
                while(iterator.hasNext()){
                    Map.Entry<Character,Integer>next=iterator.next();
                    if(next.getValue()>1){
                        sb.append(next.getKey());
                    }
                }
                s=sb.toString();
                c=s.toCharArray();
                Arrays.sort(c);
                System.out.println(new String(c));
            }
        }

    //2019.8.1华为校招海外留学专场 题目二 ( 35.7%AC)
    //给定一串字符,里面有些字符有连续出现的特点,请寻找这些连续出现字符中最长的串,
    //如果最长字串有多个,请输出字符ASCII码最小的那一串
    //输入:用cin输入一串字符, 如:aaabbbbbccccccccczzzzzzzzz
    //输出:用cout输出其中最长的字串。如:ccccccccc
    //说明:c和z都可以选,但是c比z的ASCII码小
    import java.util.*;
    public class Main{
        public static void main(String[] args)
        {
            Scanner scanner=new Scanner(System.in);
            String s=scanner.nextLine();
            char c[]=s.toCharArray();
            Arrays.sort(c);
            Map<Character,Integer>map=new HashMap<Character,Integer>();
                int p=0;
                for(int i=1;i<c.length;i++) {
                    if(c[p]==c[i])
                    {
                            map.put(c[p],i-p+1);
                    }
                    else {
                        p=i;
                        map.put(c[p],1);
                    }
                }
                int maxValue=Integer.MIN_VALUE;
                char c1=' ';
                Iterator<Map.Entry<Character,Integer>>iterator=map.entrySet().iterator();
                while(iterator.hasNext()) {
                    Map.Entry<Character,Integer>next=iterator.next();
                    maxValue=Math.max(maxValue, next.getValue());
                    
                }
                for(Character character :map.keySet()) {
                    if(map.get(character).equals(maxValue)) {
                        c1=character;
                        break;
                    }
                }
                StringBuilder stringBuilder=new StringBuilder();
                for(int i=0;i<maxValue;i++) {
                    stringBuilder.append(c1);
                    
                }
                System.out.println(stringBuilder.toString());
        }
    }
    //2019.8.1华为校招海外留学专场 题目三  没有做出来
    //已知某小镇的房子沿直线分布,给定一个有序整型数组arr,里面的每个值代表小镇每栋房子的一维坐标点
    //现在需要建N个广告牌,广告牌只能建在这些坐标点上,使得每个坐标点离广告牌的总距离最短,请返回这个最短的总距离
    //输入:1<=N<=arr的长度;每个坐标点以最近的广告牌距离作为该坐标点离广告牌的距离;
    //输入中最后一个为N值,其余为arr值,需要考生自行处理,示例输入:1 2 3 4 5 1000 2
    //输出:输出为所有坐标点离广告牌的最短总距离, 示例输出:6
    //说明:arr=[1,2,3,4,5,1000],N=2。第一个广告牌建立在3位置,第二个广告牌建立1000位置。这样arr上的点到广告牌位置距离
    //分别为2,1,0,1,2,0,总距离为6,没有任何方案总距离更短,故返回6

     

     

     

     

     

     

     

     

     

    展开全文
  • 这一呆就才不多2个月,在这段时间内面试了差不多10家公司,有一半都给了Offer,但是没有想去的公司。原因:1、就是薪资给的少了点;2、薪资给的还可以,但是没有什么空间可以提升自己。经过一段时间朋友介绍,让我把...
  • 白话讲解排序算法

    2020-05-16 11:49:20
    我是自动化专业的应届研究生,最终拿到了tplink、华为、vivo等公司的ssp的offer,分享自己学习过的计算机基础知识(C语言+操作系统+计算机网络+linux)以及数据结构与算法的相关知识,保证看完让你有所成长。...
  • 拿到华为上研所无线嵌入式超低白菜价offer,奉劝各位找工作的小伙伴,真心不要去参加华为的优招和实习,坑死人,原因有二,其一,优招时间太早,准备的不够充分,而且面试成绩与秋招一起排序,一起发offer,性价比太...
  • 背景:211渣硕,电气专业转JAVA后台,看书很少多数是在刷面经,能找到工作实属侥幸,现献上自己的面经,希望能帮助到别人部分面试结果:先上总结:如果实力不够硬建议还是海...感觉上华为小米海康比纯互联网公司的难...
  • 关于字符串排序

    2016-09-09 10:34:10
    昨晚,一起准备找工作的同学在研究一道算法题,这位大牛,已经拿了华为offer还这么拼,叫我们这些投了简历杳无回音的人 额,闲话不多说了,原题要求如下:  case 1: 忽略大小写排序, 如:"Type", 排序后 ...
  • 2019华为优招-南研所

    千次阅读 热门讨论 2018-08-20 20:36:28
    就读于皇家水利学院(哈哈哈),可惜我是苦逼的计算机专业,毫无优势可言,幸亏还是个211,才有点胆量去参加了华为的2019年的优招面试,面试流程如下,全部流程我也没走完,要是能走完就很棒棒哟(意味着拿offer),...
  • 昨天收到了offer,总结一下华为的这次软件类 经历,总结一下自己的不足,也共享一下 鄙人的一点 小经验。 机试时间好像是一个半小时,我是在学校参加的,选择的是JAVA类(说明一下,华为的机试 可能都是有要求,...
  • 我是自动化专业的应届研究生,最终拿到了tplink、华为、vivo等公司的ssp的offer,分享自己学习过的计算机基础知识(C语言+操作系统+计算机网络+linux)以及数据结构与算法的相关知识,保证看完让你有所成长。...
  • 2020.4.15华为实习招聘笔试题第三题

    千次阅读 2020-04-16 09:46:44
    很可惜,当时没做出来,写了个bug调了一个多小时,但是思路是对的。 leetcode刷久了,对各种输入的处理能力不够,第一题本来很简单,也是写了一个bug把...使用map映射 使用拓扑排序判环 #include <bits/stdc++....
  • 方法1:快速排序,输出前k个数,参考剑指offer面试题30 不知道问题出在哪,在OJ系统提交木有通过,提示答案错误,在此把代码贴出来。#include #include using namespace std; #define N 100 int RandomInt(int,int);...
  • 这一呆就才不多2个月,在这段时间内面试了差不多10家公司,有一半都给了Offer,但是没有想去的公司。原因:1、就是薪资给的少了点;2、薪资给的还可以,但是没有什么空间可以提升自己。经过一段时间朋友介绍,让我把...
  • 编程之旅-Day5

    2019-03-21 23:08:32
    (2)华为机试题-0交换排序 (3)华为2018届校招勇敢星实习生招聘笔试 例1.整数翻转求和 例2.掷骰子 (4)拓展练习:华为机试题 1.剑指Offer 面试题11:旋转数组中的最小数字 题目描述: 把一个数组最开始...
  • 编程之旅-Day45

    2019-05-02 23:53:22
    目录 Day45-学习内容: 1.剑指Offer 面试题6:从尾到头打印链表 面试题18:删除链表的节点(牛客网无,...3.华为机试题 例1:字符串排序 例2:查找兄弟单词 例3:数据分类处理 1.剑指Offer 面试题6:从...
  • 编程之旅-Day47

    2019-05-04 23:56:41
    面试题25:合并两个排序链表 2.华为机试题 例1:字符串运用-密码截取 例2:整数和IP地址间的转换 例3:图片整理 例4:蛇形矩阵 1.剑指Offer 面试题24:反转链表 题目描述:输入一个链表,反转链表后,输出新链表...
  • 小水硕面试经验谈

    千次阅读 2013-10-13 18:09:36
    1、华为,云计算开发工程师,是我面的第一家公司,也是第一个发offer的,签约面谈会时,考虑到薪酬和发展,以及自己小水硕的原因,就果断签了。  华为经典三道上机题,答对两道题进入专业面试,主要是问了操作系统...
  • 面试要点

    2020-10-28 19:17:44
    常见考点:20 227 简直offer62 二叉树的前中后序遍历 105 106 树突994 695 559 200 进制转换相互转换了解机制 滑动窗口 3 674 自定义排序 身高体重 179 排列组合60 简单的动态规划 70 53 区间合并56 ...
  • 二维数组中的查找

    2018-05-22 21:38:15
    题目描述在一个二维数组中,每一行都按照从左到右...华为的题目基本上用c写的,剑指offer开始想用python来写了,慢慢的练习一下喽###两种思路:# -*- coding:utf-8 -*-class Solution: # array 二维列表 def Fi...
  • 最后拿到了百度,intel,360,oppo,vipkid,猎豹移动,秒针系统,农行总行的offer华为还在录用排序,期间因为时间问题放弃了一些笔试和面试。从牛客网学到了很多,自己总结了一些知识点(C++后台方向),分享给...
  • 最后拿到了百度,intel,360,oppo,vipkid,猎豹移动,秒针系统,农行总行的offer华为还在录用排序,期间因为时间问题放弃了一些笔试和面试。从牛客网学到了很多,自己总结了一些知识点(C++后台方向),分享给...
  • 记录下秋招一路的磕磕绊绊~许愿一个心仪的offer~~ 2020-8-10~2020-8-14 华为 AI工程师 两轮技术面+一轮主管面 技术面(一面) 1、自我介绍 2、询问项目 3、询问实习做的项目(思路要清晰,循序渐进,循序展开,...
  • 出现次数的问题

    2020-07-02 10:53:16
    1【第一个只出现一次的字符】–剑指offer 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).(从0开始计数) 2【字符...
  • C++程序员面试宝典

    热门讨论 2013-04-01 13:36:19
    aren't likely to offer 20 面试题3 What would you like to accomplish that you weren't able to accomplish in your last position 20 面试题4 How have your career motivations changed over the past few ...
  • 面试题199 介绍STL,详细说明STL如何实现vector(华为面试 题) 面试题200 分析Visual C++程序出错的原因 面试题201 继承和多态有何区别 面试题202 指针和引用有何区别?传引用比传指针安全,为什么 面试题203 参数...
  • 《剑指 offer》 非常经典的一本书,学算法的人必刷。但是要注意了,这边书里面的题目是用 C++写的,如果你是 Java 开发人员可能会有点影响。但是要记住学习算法最关键的还是解题思路和方法,用什么语言实现是其次的...

空空如也

空空如也

1 2
收藏数 31
精华内容 12
关键字:

华为offer排序