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
这场周赛有两道深度优先遍历的题目,这个知识点还是非常重要的,以后也要多做点这方面的题目。

posted @ 2019-05-12 11:28  Leo_26  阅读(188)  评论(0编辑  收藏  举报