• LeetCode Weekly Contest 70 A B C D


    A. K-th Symbol in Grammar

    Description

    On the first row, we write a 0. Now in every subsequent row, we look at the previous row and replace each occurrence of 0 with 01, and each occurrence of 1 with 10.

    Given row N and index K, return the K-th indexed symbol in row N. (The values of K are 1-indexed.) (1 indexed).

    Example:
    row 1: 0
    row 2: 01
    row 3: 0110
    row 4: 01101001
    

    思路

    递归

    Code

    class Solution {
    public:
        int kthGrammar(int N, int K) {
            if (N==1) return 0;
            return kthGrammar(N-1, (K+1)/2) ? ((K%2)? 1 : 0) : ((K%2) ? 0 : 1);
        }
    };
    

    B. Split BST

    Description

    Given a Binary Search Tree (BST) with root node root, and a target value V, split the tree into two subtrees where one subtree has nodes that are all smaller or equal to the target value, while the other subtree has all nodes that are greater than the target value. It's not necessarily the case that the tree contains a node with value V.

    Additionally, most of the structure of the original tree should remain. Formally, for any child C with parent P in the original tree, if they are both in the same subtree after the split, then node C should still have the parent P.

    You should output the root TreeNode of both subtrees after splitting, in any order.

    Example 1:
    
    Input: root = [4,2,6,1,3,5,7], V = 2
    Output: [[2,1],[4,3,6,null,null,5,7]]
    Explanation:
    Note that root, output[0], and output[1] are TreeNode objects, not arrays.
    
    The given tree [4,2,6,1,3,5,7] is represented by the following diagram:
    
          4
        /   
      2      6
     /     / 
    1   3  5   7
    
    while the diagrams for the outputs are:
    
          4
        /   
      3      6      and    2
            /            /
           5   7         1
    

    思路

    递归

    Code

    class Solution {
    public:
        vector<TreeNode*> splitBST(TreeNode* root, int V) {
            if (!root) {
                vector<TreeNode*> ret = {NULL, NULL};
                return ret;
            }
            if (root->val==V) {
                vector<TreeNode*> ret = {root, root->right};
                root->right = NULL;
                return ret;
            }
            vector<TreeNode*> l = splitBST(root->left, V),
                r = splitBST(root->right, V);
            if (root->val < V) {
                root->right = r[0];
                vector<TreeNode*> ret = {root, r[1]};
                return ret;
            }
            else {
                root->left = l[1];
                vector<TreeNode*> ret = {l[0], root};
                return ret;
            }
        }
    };
    

    C. Swap Adjacent in LR String

    Description

    In a string composed of 'L', 'R', and 'X' characters, like "RXXLRXRXL", a move consists of either replacing one occurrence of "XL" with "LX", or replacing one occurrence of "RX" with "XR". Given the starting string start and the ending string end, return True if and only if there exists a sequence of moves to transform one string to the other.

    Example:
    
    Input: start = "RXXLRXRXL", end = "XRLXXRRLX"
    Output: True
    Explanation:
    We can transform start to end following these steps:
    RXXLRXRXL ->
    XRXLRXRXL ->
    XRLXRXRXL ->
    XRLXXRRXL ->
    XRLXXRRLX
    

    思路

    由规则,(L)只能一路向左移动,(R)只能一路向右移动。

    所以,前后所有(L)(R)的相对位置关系不变,且(s2)(L)的位置只能在(s1)中对应的(L)的位置的左边,(s2)(R)的位置只能在(s1)中对应的(R)的位置的右边。

    Code

    class Solution {
    public:
        struct node {
            char c; int p;
        };
        bool canTransform(string start, string end) {
            int len = start.size();
            if (len != end.size()) return false;
            vector<node> v1, v2;
            for (int i = 0; i < len; ++i) {
                if (start[i] != 'X') {
                    v1.push_back({start[i], i});
                }
            }
            for (int i = 0; i < len; ++i) {
                if (end[i] != 'X') {
                    v2.push_back({end[i], i});
                }
            }
            int n = v1.size();
            if (n != v2.size()) return false;
            for (int i = 0; i < n; ++i) {
                if (v1[i].c != v2[i].c) return false;
                if (v1[i].c=='L') { if (v1[i].p < v2[i].p) return false; }
                else { if (v1[i].p > v2[i].p) return false; }
            }
            return true;
        }
    };
    
    

    D. Swim in Rising Water

    Description

    On an N x N grid, each square grid[i][j] represents the elevation at that point (i,j).

    Now rain starts to fall. At time t, the depth of the water everywhere is t. You can swim from a square to another 4-directionally adjacent square if and only if the total elevation of both squares is at most t. You can swim infinite distance in zero time. Of course, you must stay within the boundaries of the grid during your swim.

    You start at the top left square (0, 0). What is the least time until you can reach the bottom right square (N-1, N-1)?

    Example 1:
    
    Input: [[0,2],[1,3]]
    Output: 3
    Explanation:
    At time 0, you are in grid location (0, 0).
    You cannot go anywhere else because 4-directionally 	adjacent neighbors have a higher elevation than t = 0.
    
    You cannot reach point (1, 1) until time 3.
    When the depth of water is 3, we can swim anywhere inside the grid.
    Example 2:
    
    Input: [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
    Output: 16
    Explanation:
     0  1  2  3  4
    24 23 22 21  5
    12 13 14 15 16
    11 17 18 19 20
    10  9  8  7  6
    
    The final route is marked in bold.
    We need to wait until time 16 so that (0, 0) and (4, 4) are connected.
    

    思路

    题意即 找一条(0, 0)到(n-1,n-1)的路径,上面的最大值最小

    二分 最大值,然后判断连通性,用 记忆化搜索 即可。

    Code

    class Solution {
    private:
        bool vis[55][55], flag[55][55], temp[55][55];
        bool can(int x, int y, int n, vector<vector<int>>& mp) {
            if (vis[x][y]) return flag[x][y];
            vis[x][y] = true;
            if (!temp[x][y]) return flag[x][y] = false;
            if ((x-1>=0&&can(x-1,y,n,mp)) || (x+1<n&&can(x+1,y,n,mp))
                 || (y-1>=0&&can(x,y-1,n,mp)) || (y+1<n&&can(x,y+1,n,mp))) return flag[x][y] = true;
            else return flag[x][y] = false;
        }
        bool ok(vector<vector<int>>& mp, int n, int x) {
            memset(vis, 0, sizeof vis);
            memset(flag, 0, sizeof flag);
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (mp[i][j] > x) temp[i][j] = 0;
                    else temp[i][j] = 1;
                }
            }
            if (mp[0][0] <= x) {
                flag[0][0] = vis[0][0] = 1;
                bool hh = can(n-1, n-1, n, mp);
                return hh;
            }
            else return false;
        }
    public:
        int swimInWater(vector<vector<int>>& grid) {
            int n = grid.size(), minn = INT_MAX, maxx = 0;
            for (int i = 0; i < n; ++i) {
                for (int j = 0; j < n; ++j) {
                    minn = min(minn, grid[i][j]), maxx = max(maxx, grid[i][j]);
                }
            }
            int l = minn, r = maxx;
            while (l < r) {
                int mid = l+r >> 1;
                if (ok(grid, n, mid)) r = mid;
                else l = mid+1;
            }
            return l;
        }
    };
    
  • 相关阅读:
    java接口鉴权之sign签名校验与JWT验证
    完整的后端开发流程-深入浅出Java线程池:使用篇
    Java多线程加法计算--Java识别静态验证码和动态验证码
    超全面设计指南:如何做大屏数据可视化设计?
    vue+echarts+datav大屏数据展示及实现中国地图省市县下钻
    开源」目前见过的最好的开源OA产品架构师之路(一):何时选用合适的语言
    如何做大屏数据可视化设计?
    Spring项目方便调试打印请求信息点击跳转到方法
    Echart生成的报表导出为PDF
    java环境变量一键配置
  • 原文地址:https://www.cnblogs.com/kkkkahlua/p/8412984.html
Copyright © 2020-2023  润新知