LeetCode华为模拟面试

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

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

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

给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(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]

示例 2:

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

示例 3:

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

示例 4:

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

提示:

  • 树中的节点数介于 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为边界的正方形

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

示例 1:

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

示例 2:

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

提示:

  • 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);
    }
}

三、串联所有单词的子串

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

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

示例 1:

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

示例 2:

输入:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
输出:[]

我的解法

看到这道题的时候,一度想放弃,因为没有想到什么巧妙的解法。最后也是用了一个大暴力的方法,最后提交到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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为手撕题leetcode是指华为面试中要求候选人现场手撕leetcode题目。这种面试方式常用于评估候选人的编程能力和解决问题的能力。 使用华为手撕题leetcode的优点是能够直接考察候选人的编程能力和思维逻辑。面试官可以根据候选人的解题过程和代码实现来评估其算法和编程能力,从而更直观地了解候选人的能力水平。 使用这种面试方式还可以考察候选人在时间有限的情况下解决问题的能力。手撕编码题要求候选人在短时间内完成编写算法和实现代码。这种情况下,候选人需要通过灵活运用算法知识、代码实现技巧和系统思考能力,快速找到解决问题的方法。 然而,华为手撕题leetcode也存在一定的局限性。一方面,手撕题leetcode可能只考察候选人的算法和编程能力,而忽略了其他的技术要求,如系统设计、代码架构等。另一方面,由于题目限定在leetcode的题库中,候选人可能通过事先刷题来准备,从而提前得到题目的答案,影响面试评估的公正性。 为了克服这些限制,华为还会在面试中结合其他的问题和项目经验,综合评估候选人的整体能力。此外,华为还会要求候选人进行coding test,即在指定时间内以线上编码的方式解决问题,更直观地了解候选人的编码能力。 总的来说,华为手撕题leetcode是一种评估候选人编程能力和解决问题能力的有效方式,但也需要综合考虑其他方面的能力和筛选方法,以评估候选人的真实水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值