Leetcode 模拟面试Ⅱ 记录

为什么难度从2easy1medium突然就变成了2medium1hard,自闭自闭
在这里插入图片描述

1.最大宽度坡(中等)
题目链接:https://leetcode-cn.com/problems/maximum-width-ramp/
在这里插入图片描述
差点就死在第一题手上了…

最开始的思路是暴力+剪枝,剪枝的思路就是对应每一个起始点得到的最长距离,作为下一次比较的初始距离。比如样例1里面先对起始点6求最大结果,为2(2 - 0),下一次对起始点0求解时,直接从 0 + 2 开始往后遍历。

然后就TLE了一个50000个数据的递减自闭样例,所以重新想算法。

尝试把数组按值排序,然后根据下标找最大差值:
A : [0, 1, 2, 5, 6, 8]
index : [1, 4, 3, 5, 0, 2]
这里找到的最大差值就是 5 - 1 = 4,但是不是全局最大值和最小值的差值,而是将下标数组 index 分为前后两部分,前半部分的最小值和后半部分的最大值的差值是我们需要的,所以前缀最小值数组,后缀最大值数组,找相邻下标的最大差值即可。同样以样例1为例,最值数组如下(注意是对index数组做):
minimum::[1, 1, 1, 1, 0, 0]
maximum:[5, 5, 5, 5, 2, 2]

代码如下:

class Solution {
public:
    struct Node {
        int val;
        int index;
    }a[50005];

    static bool cmp(Node a, Node b) {
        if(a.val == b.val) {
            return a.index < b.index;
        } 
        return a.val < b.val;
    }

    int maxWidthRamp(vector<int>& A) {
        for(int i = 0; i < A.size(); i++) {
            a[i].val = A[i];
            a[i].index = i;
        }
        int len = A.size();
        sort(a, a + len, cmp);

        vector<int> minimum(len, 0);
        vector<int> maximum(len, 0);

        minimum[0] = a[0].index;
        maximum[len - 1] = a[len - 1].index;
        for(int i = 1; i < len; i++) {
            minimum[i] = min(minimum[i - 1], a[i].index);
        }
        for(int i = len - 2; i >= 0; i--) {
            maximum[i] = max(maximum[i + 1], a[i].index);
        }

        int res = 0;
        for(int i = 0; i < len - 1; i++) {
            res = max(res, maximum[i + 1] - minimum[i]);
        }

        return res;
    }
};

2.具有所有最深结点的最小子树(中等)
题目链接:https://leetcode-cn.com/problems/smallest-subtree-with-all-the-deepest-nodes/
在这里插入图片描述在这里插入图片描述
对树的掌握还是有点差,所以代码很乱,思路是dfs求层数并记录到数组floor中,每个节点根据其值(因为题目说了唯一)记录父节点及其左右(father[i][0]记录父节点值,father[i][1]记录是父节点的左子树还是右子树)。然后对所有的最大深度节点逐个求其父节点并放到数组cnt中,直到cnt中只有一个节点,就是要求的节点,再根据其father数组逆推路径,最后从根节点按照路径找到该TreeNode结点。

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int father[505][2];
    int floor[505];
    int mxval = 0;
    int mxfloor = 0;

    void dfs(TreeNode* root, int level) {
        floor[root->val] = level;
        //printf("floor[%d] = %d\n", root->val, level);
        mxval = max(mxval, root->val);
        if(root->left != NULL) {
            dfs(root->left, level + 1);
            father[root->left->val][0] = root->val;
            father[root->left->val][1] = 0;
        }
        if(root->right != NULL) {
            dfs(root->right, level + 1);
            father[root->right->val][0] = root->val;
            father[root->right->val][1] = 1;
        }
    }

    TreeNode* subtreeWithAllDeepest(TreeNode* root) {
        if(root == NULL) {
            return root;
        }
        father[root->val][0] = -1;
        mxval = max(mxval, root->val);
        if(root->left == NULL && root->right == NULL) {
            return root;
        }
        if(root->left != NULL) {
            dfs(root->left, 1);
            father[root->left->val][0] = root->val;
            father[root->left->val][1] = 0;
        }
        if(root->right != NULL) {
            dfs(root->right, 1);
            father[root->right->val][0] = root->val;
            father[root->right->val][1] = 1;
        }
        for(int i = 0; i <= mxval; i++) {
            //printf("floor[%d] = %d\n", i, floor[i]);
            mxfloor = max(mxfloor, floor[i]);
            
        }
        cout << "max_floor = " << mxfloor << endl;
        queue<int> q;
        for(int i = 0; i <= mxval; i++) {
            if(floor[i] == mxfloor) {
                q.push(i);
            }
        }
        
        
        int ans = 0;
        if(q.size() == 1) {
            ans = q.front();
        } else {
            int cnt[505] = {0};
            int count = 0;
            while(1) {
                while(!q.empty()) {
                    if(!cnt[father[q.front()][0]]) {
                        cnt[father[q.front()][0]] = 1;
                        count++;
                    }
                    q.pop();
                }
                if(count == 1) {
                    break;
                }
                for(int i = 0; i <= mxval; i++) {
                    if(cnt[i] == 1) {
                        q.push(i);
                    }
                }
                fill(cnt, cnt + 505, 0);
                count = 0;
            }
            for(int i = 0; i <= mxval; i++) {
                if(cnt[i] == 1) {
                    cout << "find! value = " << i << endl;
                    ans = i;
                    break;
                }
            }
        }
        printf("ans = %d\n", ans);
        
        
        

        stack<int> s;
        while(father[ans][0] != -1) {
            s.push(father[ans][1]);
            ans = father[ans][0];
        }
        while(!s.empty()) {
            if(s.top() == 0) {
                root = root->left;
            } else {
                root = root->right;
            }
            s.pop();
        }

        return root;
    }
};

看了题解之后emmmmm,照猫画虎来一遍吧:
第一遍dfs求最大深度
第二遍answer(另一个深搜函数)返回最终结点

answer的原理:
最底层遇到最大深度结点则返回该节点,否则返回NULL;
中间层分别调用左右子树的answer结果,若左右子树结果均不为NULL,说明都含最大深度,则返回当前节点,否则哪个子树结果不为NULL就返回该子树结果。若两子树结果均为NULL说明后代无最大深度节点,返回NULL;

代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    map<TreeNode*, int> depth;
    int max_depth = -1;

    TreeNode* subtreeWithAllDeepest(TreeNode* root) {
        depth[NULL] = -1;
        dfs(root, NULL);
        return answer(root);
    }

    void dfs(TreeNode* root, TreeNode* parent) {
        if(root != NULL) {
            depth[root] = depth[parent] + 1;
            max_depth = max(max_depth, depth[root]);
            dfs(root->left, root);
            dfs(root->right, root);
        }
    }

    TreeNode* answer(TreeNode* root) {
        if(root == NULL || depth[root] == max_depth) {
            return root;
        }
        TreeNode* L = answer(root->left);
        TreeNode* R = answer(root->right);
        if(L != NULL && R != NULL) {
            return root;
        }
        if(L != NULL) {
            return L;
        }
        if(R != NULL) {
            return R;
        }
        return NULL;
    }
};

3.猜猜这个单词(困难)
题目链接:https://leetcode-cn.com/problems/guess-the-word/
在这里插入图片描述
开始开心的二分,然后发现毫无规律,最后也没出来。

题解看不懂,等哪天看懂了再补全,告辞!

猜你喜欢

转载自blog.csdn.net/weixin_42396397/article/details/106109630