当前位置:   article > 正文

LeetCode华为模拟面试_面试手撕代码是在电脑上写吗

面试手撕代码是在电脑上写吗

这是一篇灌水的博客。
今天收到了华为2012实验室的面试通知,HR老师说手撕代码很重要,遂在LeetCode上进行了一次华为题库的模拟面试,下面是这次模拟面试的三道题目。
华为的面试一般要求在记事本中写代码,有时也会要求在纸上写代码,所以建议大家在练习的时候尽量还是不要在本地IDE写代码。像这种模拟面试尽量还是直接在LeetCode的网页上编写程序。

面试结果:全部通过
总时长:1 小时 30 分
耗时:46 分 19 秒
答题数:3/3
  • 1
  • 2
  • 3
  • 4

一、二叉搜索树转化为累加和

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。

提醒一下,二叉搜索树满足下列约束条件:

  • 节点的左子树仅包含键 小于 节点键的节点。
  • 节点的右子树仅包含键 大于 节点键的节点。
  • 左右子树也必须是二叉搜索树。

**注意:**本题和 1038: https://leetcode-cn.com/problems/binary-search-tree-to-greater-sum-tree/ 相同

示例 1:

img

输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
  • 1
  • 2

示例 2:

输入:root = [0,null,1]
输出:[1,null,1]
  • 1
  • 2

示例 3:

输入:root = [1,0,2]
输出:[3,3,2]
  • 1
  • 2

示例 4:

输入:root = [3,2,4,1]
输出:[7,9,4,10]
  • 1
  • 2

提示:

  • 树中的节点数介于 0104 之间。
  • 每个节点的值介于 -104104 之间。
  • 树中的所有值 互不相同
  • 给定的树为二叉搜索树。

我的解法

树中的节点根据值从大到小的顺序依次改变就可以了。二叉树的三个遍历中,中序遍历是按照排序顺序的,不过这里需要先遍历右孩子,最后遍历左孩子。整个过程需要遍历所有的节点一次,所以时间复杂度为 O ( n ) O(n) O(n)。具体的代码如下所示

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode convertBST(TreeNode root) {
        if(root==null){
            return root;
        }
        convertBST(root, 0);
        return root;
    }

    private int convertBST(TreeNode root, int base){
        if(root.right==null){
            root.val = root.val + base;
            base = root.val;
        }else{
            base = convertBST(root.right, base);
            root.val = root.val + base;
            base = root.val;
        }

        if(root.left!=null){
            base = convertBST(root.left, base);
        }

        return base;

        
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

二、 最大的以1为边界的正方形

给你一个由若干 01 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0

示例 1:

输入:grid = [[1,1,1],[1,0,1],[1,1,1]]
输出:9
  • 1
  • 2

示例 2:

输入:grid = [[1,1,0,0]]
输出:1 
  • 1
  • 2

提示:

  • 1 <= grid.length <= 100
  • 1 <= grid[0].length <= 100
  • grid[i][j]01

我的解法

这道题没有想到太好的解法,写了个大遍历,只是在遍历的时候先判断目标正方向的最左上和最右下位置的元素,并且只考察比当前最大正方形更大的正方形,来起到一个剪枝的作用。这个算法的时间复杂度的分析比较复杂。下面是具体的Java程序实现

class Solution {
    public int largest1BorderedSquare(int[][] grid) {
        int n = grid.length;
        int m = grid[0].length;

        if(n==0 || m==0){
            return 0;
        }

        int max = -1;
        for(int i=0; i<n; i++){
            for(int j=0; j<m; j++){
                if(grid[i][j]==1){
                    max = 0;
                    break;
                }
            }
        }
        if(max==-1){
            return 0;
        }

        
        for(int i=0; i+max<n; i++){
            for(int j=0; j+max<m; j++){
                int b = Math.min(n-i, m-j)-1;
                for(int max1=max; max1<=b; max1++){
                    if(grid[i][j]==1 && grid[i+max1][j+max1]==1){
                        boolean flag = true;
                        for(int k=0; k<=max1; k++){
                            if(grid[i][j+k]==0 || grid[i+max1][j+k]==0 || 
                            grid[i+k][j]==0 || grid[i+k][j+max1]==0){
                                flag = false;
                                break;
                            }
                        }
                    
                        if(flag){
                            max = max1;
                        }
                    }
                }
                
            }
        }

        return (max+1)*(max+1);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

三、串联所有单词的子串

给定一个字符串 s 和一些长度相同的单词 **words。**找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

示例 1:

输入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

示例 2:

输入:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
输出:[]
  • 1
  • 2
  • 3
  • 4

我的解法

看到这道题的时候,一度想放弃,因为没有想到什么巧妙的解法。最后也是用了一个大暴力的方法,最后提交到LeetCode系统结果显示运行时间1500多毫秒。下面是具体的Java程序实现

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new LinkedList<>();
        int n = s.length();
        int k = words.length;
        if(n==0 || k==0 || n<k){
            return res;
        }

        int m = words[0].length();
        if(m==0){
            return res;
        }

        for(int i=0; i+k*m<=n; i++){
            int[] visited = new int[k];
            int ptr = i;
            while(ptr<n){
                boolean flag = false;
                for(int j=0; j<k; j++){
                    if(visited[j]==0 && words[j].equals(s.substring(ptr, ptr+m))){
                        visited[j] = 1;
                        ptr += m;
                        flag = true;
                        break;
                    }
                }

                if(!flag){
                    break;
                }
            }

            if(ptr==i+k*m){
                res.add(i);
            }
        }
        return res;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/642712
推荐阅读
相关标签
  

闽ICP备14008679号