字节可不和你闹,3道hard起步

231 阅读4分钟

image.png

本文就来看看这 3 道题目。

最大矩形有 2 道可能的题目,我们都来看下

84.  柱状图中最大的矩形

题目链接

image.png

对于答案矩形也就是最大面积矩形,他的高一定是 heights 中的某个元素,那么可以遍历 heights 并且假设他是高度,那么只要计算出两边的长度即可,长度如何计算?还是用到单调栈,只不过要计算 2 次,第一次是左边比当前元素小的,第二次是右边比当前元素小的。最后计算面积即可。

var largestRectangleArea = function(heights) {
    let stack=new Stack()
    let left=[]
    let right=[]
    for(let i=0;i<heights.length;i++){
        let ele=heights[i]
        while(!stack.isEmpty()&&stack.peek()[0]>=ele){
            stack.pop()
        }
        if(!stack.isEmpty()){
            left[i]=stack.peek()[1]
        }else {
            left[i]=-1
        }
        stack.push([ele,i])
    }
    stack=new Stack()
    for(let i=heights.length-1;i>=0;i--){
        let ele=heights[i]
        while(!stack.isEmpty()&&stack.peek()[0]>=ele){
            stack.pop()
        }
        if(!stack.isEmpty()){
            right[i]=stack.peek()[1]
        }else {
            right[i]=heights.length
        }
        stack.push([ele,i])
    }
    let res=0
    for(let i=0;i<heights.length;i++){
        let ele=heights[i]
        let cur=ele*(right[i]-left[i]-1)
        res=Math.max(res,cur)
    }
    return res
};

Stack 类的定义在这里

85.  最大矩形

题目链接

image.png

看下边的橙色的部分,这完全就是上一道题呀!

image.png

那么直接调用上一道题 largestRectangleArea 方法即可。

var maximalRectangle = function(matrix) {
    let m=matrix.length
    let n=matrix[0].length
    let rowHeights=[]
    let res=0
    for(let i=0;i<m;i++){
        rowHeights[i]=[]
        for(let j=0;j<n;j++){
            let hei=0
            for(let k=i;k>=0;k--){
                if(matrix[k][j]==1){
                    hei++
                }else{
                    break
                }
            }
            rowHeights[i].push(hei)
        }
        let cur=largestRectangleArea(rowHeights[i])
        res=Math.max(res,cur)
    }
    return res
};

297.  二叉树的序列化与反序列化

题目链接

image.png

image.png

本题可以参考这篇文章

如果给你一棵二叉树的前序遍历结果,你是否能够根据这个结果还原出这棵二叉树呢?

答案是也许可以,也许不可以,具体要看你给的前序遍历结果是否包含空指针的信息。如果包含了空指针,那么就可以唯一确定一棵二叉树,否则就不行。

那么前中后序哪一种遍历顺序,只要序列化的结果中包含了空指针的信息,就能还原出唯一的一棵二叉树了?

但很不幸,正确答案是,即便你包含了空指针的信息,也只有前序和后序的遍历结果才能唯一还原二叉树,中序遍历结果做不到。因为前序/后序遍历的结果中,可以确定根节点的位置,而中序遍历的结果中,根节点的位置是无法确定的。

结论

  1. 如果你的序列化结果中不包含空指针的信息,且你只给出一种遍历顺序,那么你无法还原出唯一的一棵二叉树。

  2. 如果你的序列化结果中不包含空指针的信息,且你会给出两种遍历顺序,那么分两种情况:

    2.1. 如果你给出的是前序和中序,或者后序和中序,那么你可以还原出唯一的一棵二叉树。

    2.2. 如果你给出前序和后序,那么除非你的整棵树中不包含值相同的节点,否则你无法还原出唯一的一棵二叉树。

  3. 如果你的序列化结果中包含空指针的信息,且你只给出一种遍历顺序,也要分两种情况:

    3.1. 如果你给出的是前序或者后序,那么你可以还原出唯一的一棵二叉树。

    3.2. 如果你给出的是中序,那么除非你的整棵树中不包含值相同的节点,否则你无法还原出唯一的一棵二叉树。

那么我们使用前序遍历加尾节点的方式序列化。

var serialize = function(root) {
    let list=[]
    function dfs(ele){
        if(ele==null){
            list.push('#')
            return
        }
        list.push(ele.val)
        dfs(ele.left)
        dfs(ele.right)
    }
    dfs(root)
    let res=list.join(',')
    console.log(res)
    return res
};

image.png

输出

1,2,#,#,3,4,#,#,5,#,#

反序列化也是类似的操作

var deserialize = function(data) {
    let list=data.split(',')

    function deser(list){
        if(!list.length){
            return null
        }
        let root=list.shift()
        if(root==='#'){
            return null
        }
        let node=new TreeNode(root)
        node.left=deser(list)
        node.right=deser(list)
        return node
    }
    return deser(list)
};

主要是先把根元素找到,之后构造 left 和 right 节点。

10.  正则表达式匹配

题目链接

image.png

这题是动态规划,比较难想,直接看题解并记住

image.png

image.png

image.png

image.png

image.png

image.png

function isMatch(s, p) {
    let m=s.length,n=p.length
    let dp=[]
    for(let i=0;i<m+1;i++){
        dp[i]=[]
        for(let j=0;j<n+1;j++){
            dp[i][j]=false
        }
    }
    dp[0][0]=true
    for(let j=1;j<n+1;j++){
        if(p[j-1]==='*'){
            dp[0][j]=dp[0][j-2]
        }
    }
    for(let i of range(1,m+1)){
        for(let j of range(1,n+1)){
            if(s[i-1]===p[j-1]||p[j-1]==='.'){
                dp[i][j]=dp[i-1][j-1]
            } else if (p[j-1]==='*'){
                if(s[i-1]!=p[j-2]&&p[j-2]!='.'){
                    dp[i][j]=dp[i][j-2]
                }else{
                    dp[i][j]=dp[i][j-2]||dp[i-1][j]
                }
            }
        }
    }
    return dp[m][n]
};

function range(l,r){
    let res=[]
    for(let i=l;i<r;i++){
        res.push(i)
    }
    return res
}