【Leetcode】第132场周赛

版权声明:本文为博主原创文章,转载请注明出处-- https://blog.csdn.net/qq_38790716/article/details/89788128

1025. 除数博弈

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

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

选出任一 x x ,满足 0 < x < N 0 < x < N N N % x = = 0 x == 0
N x N - x 替换黑板上的数字 N N
如果玩家无法执行这些操作,就会输掉游戏。

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

示例 1:

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

示例 2:

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

思路:根据题意,很容易得出规律,当 N N 为奇数时鲍勃获胜,当 N N 为偶数时爱丽丝获胜。

class Solution {
public:
    bool divisorGame(int N) {
        if (N % 2 == 0)
            return true;
        return false;
    }
};

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

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

(如果 A A 的任何子节点之一为 B B ,或者 A A 的任何子节点是 B B 的祖先,那么我们认为 A A B 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 得出。

提示:

扫描二维码关注公众号,回复: 6157876 查看本文章
1. 树中的节点数在 25000 之间。
2. 每个节点的值介于 0100000 之间。

思路:类似于先序遍历的 d f s dfs 搜索。每搜一个节点,判断其值与 m a x n u m maxnum m i n n u m minnum 的大小并更新两者的大小;然后遍历左子树、右子树,当遍历到某个节点其左子树与右子树都为空时更新 m a x a n s maxans 的值,为 m a x n u m m i n n u m maxnum-minnum m a x a n s maxans 的较大值

/**
 * 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 maxans = 0;
    int maxAncestorDiff(TreeNode* root) {
        dfs(root, 100000, 0);
        return maxans;
    }
    void dfs(TreeNode* root, int minnum, int maxnum) {
        if (root->left == nullptr && root->right == nullptr) {
            minnum = min(minnum, root->val);
            maxnum = max(maxnum, root->val);
            //更新maxans的值
            maxans = max(maxans, maxnum - minnum);
            return;
        }
        //更新maxnum与minnum的值
        minnum = min(minnum, root->val);
        maxnum = max(maxnum, root->val);
        if (root->left) 
            dfs(root->left, minnum, maxnum);
        if (root->right)
            dfs(root->right, minnum, maxnum);
    }
};

1027. 最长等差数列

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

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

示例 1:

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

示例 2:

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

示例 3:

输入:[20,1,15,3,10,5,8]
输出:4
解释:
最长的等差子序列是 [20,15,10,5]

思路:没有什么特别好的思路,唯有暴力破万法。查找时记录公差 A [ j ] A [ i ] A[j] - A[i] ,记录上一个公差序列数 n e x t = A [ j ] next=A[j] ,再来一层循环遍历查找公差为 A [ j ] A [ i ] A[j]-A[i] 的序列,若找到 A [ k ] n e x t = A [ j ] A [ i ] A[k]-next=A[j]-A[i] ,则更新 n e x t = A [ k ] next=A[k] ,继续查找;每一趟查找之后更新等差序列长度

class Solution {
public:
    int maxlen;
    int longestArithSeqLength(vector<int>& A) {
        if (A.size() <= 2)
            return A.size();
        for (int i = 0; i < A.size(); ++i) {
            for (int j = i + 1; j < A.size(); ++j) {
                int ans = A[j] - A[i]; //记录当前公差
                int next = A[j];  //记录上一个等差序列值
                int count = 2;
                for (int k = j + 1; k < A.size(); ++k) {
                    if (A[k] - next == ans)  {
                        count++;
                        next = A[k];
                    }
                }
                if (count > maxlen)
                    maxlen = count;
            }
        }
        return maxlen;
    }
};

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

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

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

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

给出遍历输出 S S ,还原树并返回其根节点 r o o t 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]

提示:

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

思路:用栈来存放节点。我们可以根据输入的串进行判断,首先记录 &#x27;-&#x27; 出现的次数,即为该节点所在的深度 d e p t h depth ,然后将该节点的值计算出来为 a n s ans ,并以 a n s ans 构造一个新的节点;如果当前栈中节点数量大于该节点深度,则将栈首出栈,说明该节点不是栈首的子节点,然后再判断栈首的左子节点是否为空,如果为空则将新构造的节点作为栈首的左子节点,否则作为栈首的右子节点,将新构造的节点入栈;最后将栈中多余的节点出栈,只剩下一个节点即根节点,返回该节点

/**
 * 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:
    TreeNode* recoverFromPreorder(string S) {
        stack<TreeNode*> st;
        int i = 0;
        int n = S.size();
        while (i < n) {
            int depth = 0, ans = 0;
            //计算当前节点深度
            while (i < n && S[i] == '-') {
                depth++;
                i++;
            }
            //计算节点值
            while (i < n && S[i] != '-') {
                ans = ans * 10 + S[i] - '0';
                i++;
            }
            //判断是否为栈首子节点
            while (st.size() > depth)
                st.pop();
            //以ans构造新节点
            TreeNode* pNode = new TreeNode(ans);
            //如果栈首左节点或右节点为空,则将新构造的节点作为栈首子节点
            if (!st.empty() && st.top()->left == nullptr) 
                st.top()->left = pNode;
            else if(!st.empty())
                st.top()->right = pNode;
            //将新构造的节点入栈
            st.push(pNode);
        }
        //得到根节点
        while (st.size() > 1)
            st.pop();
        return st.top();
    } 
};

猜你喜欢

转载自blog.csdn.net/qq_38790716/article/details/89788128