zoukankan      html  css  js  c++  java
  • Leetcode 第132场周赛总结

    132

    1025. 除数博弈

    爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

    最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:

    • 选出任一 x,满足 0 < x < NN % x == 0
    • N - x 替换黑板上的数字 N

    如果玩家无法执行这些操作,就会输掉游戏。

    只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。

    示例 1:

    输入:2
    输出:true
    解释:爱丽丝选择 1,鲍勃无法进行操作。
    

    示例 2:

    输入:3
    输出:false
    解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作》。
    

    思路:动态规划,f[i]表示当数字是 i 时爱丽丝是否可以赢得比赛,如果i-j时对面赢不了比赛,f[i-j]置为1,最后返回f[N]即可

    class Solution {  
    public:
        bool divisorGame(int N) {
            vector<int> f(N+1);
    
            for(int i=1;i<N+1;i++)
            {
                f[i]=0;
                for(int j=1;j<i;j++)
                {
                    if(i%j==0)
                    {
                        if(!f[i-j]) //f[i-j]表示此时对面的状态
                        {
                            f[i] = 1;
                            break;
                        }
                    }
                }
            }
            return f[N];
        }
    };
    

    ## 1026. 节点与其祖先之间的最大差值

    给定二叉树的根节点 root,找出存在于不同节点 AB 之间的最大值 V,其中 V = |A.val - B.val|,且 AB 的祖先。

    (如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)

    示例:

    输入:[8,3,10,1,6,null,14,null,null,4,7,13]
    输出:7
    解释: 
    我们有大量的节点与其祖先的差值,其中一些如下:
    |8 - 3| = 5
    |3 - 7| = 4
    |8 - 1| = 7
    |10 - 13| = 3
    在所有可能的差值中,最大值 7 由 |8 - 1| = 7 得出。
    

    思路:

    思路: 深度优先遍历,对当前节点,分别计算当前节点值与目前最小与目前最大的差值,并记录每次遍历得到的最大差值,然后更新目前最小与目前最大。

    /**
     * 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 res;
        int maxAncestorDiff(TreeNode* root) {
            res = 0;
            dfs(root,root->val,root->val);
            return res;
        }
        
        void dfs(TreeNode* root,int l,int r)
        {
            if(root==NULL) return;
            res = max(res,abs(root->val-l));
            res = max(res,abs(root->val-r));
            
            l = min(root->val,l);
            r = max(root->val,r);
            
            dfs(root->left,l,r);
            dfs(root->right,l,r);
        }
    };
    

    ## 1027. 最长等差数列

    给定一个整数数组 A,返回 A 中最长等差子序列的长度

    回想一下,A 的子序列是列表 A[i_1], A[i_2], ..., A[i_k] 其中 0 <= i_1 < i_2 < ... < i_k <= A.length - 1。并且如果 B[i+1] - B[i]( 0 <= i < B.length - 1) 的值都相同,那么序列 B 是等差的。

    示例 1:

    输入:[3,6,9,12]
    输出:4
    解释: 
    整个数组是公差为 3 的等差数列。
    

    示例 2:

    输入:[9,4,7,2,10]
    输出:3
    解释:
    最长的等差子序列是 [4,7,10]。
    

    思路:哈希表

    对数组里每一个数字都开一个哈希表,记录此数字与其他数字差值为 t 的个数。

    class Solution {
    public:
        int longestArithSeqLength(vector<int>& nums) {
            int res = 0;
            int n = nums.size();
            vector<unordered_map<int,int>> hash(n);
            for(int i=1;i<n;i++)
            {
                for(int j=0;j<i;j++)
                {
                    int t = nums[i]-nums[j];
                    hash[i][t] = hash[j][t]+1; //hash[j][t]初始为0
                    res = max(res,hash[i][t]);
                }
            }
            return res+1;
        }
    };
    

    ## 1028. 从先序遍历还原二叉树

    我们从二叉树的根节点 root 开始进行深度优先搜索。

    在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。

    如果节点只有一个子节点,那么保证该子节点为左子节点。

    给出遍历输出 S,还原树并返回其根节点 root

    示例 1:

    输入:"1-2--3--4-5--6--7"
    输出:[1,2,5,3,4,6,7]
    

    示例 2:

    输入:"1-2--3---4-5--6---7"
    输出:[1,2,5,3,null,6,null,4,null,7]
    

    示例 3:

    输入:"1-401--349---90--88"
    输出:[1,401,null,349,88,90]
    

    提示:

    • 原始树中的节点数介于 11000 之间。
    • 每个节点的值介于 110 ^ 9 之间。

    思路:做了注释,代码思路很清晰,要注意的是字符串序列需要转化成数字形式。

    /**
     * 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 pos = 0; //记录当前遍历到的位置,总指针
        string T;
        inline int read_val(int p) {
            int x = 0;
            for (; p < T.length() && isdigit(T[p]); ++ p)
                x = (x * 10) + (T[p] - '0');
            return x;
        }
        TreeNode* Dfs(int dep) {
            int cur = 0; //记录 '-' 的个数,表示下一个节点的深度
            for (int j = pos; j < T.length() && T[j] == '-'; ++ j) ++ cur;
            if (cur != dep) return NULL;
            pos += cur;
            TreeNode *u = new TreeNode(read_val(pos));
            while (pos < T.length() - 1 && isdigit(T[pos])) ++ pos; //跳过第一个数字后面的数字,在函数里已经计算过了
            u -> left = Dfs(dep + 1);
            u -> right = Dfs(dep + 1);
            return u;
        }
        TreeNode* recoverFromPreorder(string S) {
            T = S; return Dfs(0);
        }
        
    };
    

    这一题代码来自这位大神:zjp-shadow
    这场周赛有两道深度优先遍历的题目,这个知识点还是非常重要的,以后也要多做点这方面的题目。

  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/lyc1226/p/10851489.html
Copyright © 2011-2022 走看看