5024. 除数博弈
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N
。在每个玩家的回合,玩家需要执行以下操作:
- 选出任一
x
,满足0 < x < N
且N % x == 0
。 - 用
N - x
替换黑板上的数字N
。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True
,否则返回 false
。假设两个玩家都以最佳状态参与游戏。
示例 1:
输入:2 输出:true 解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2:
输入:3 输出:false 解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
提示:
1 <= N <= 1000
思路:偶数经过操作后可以是偶数或者奇数,而奇数经过操作后只能是偶数。所以一开始是偶数爱丽丝会赢,反之,鲍勃赢。
class Solution {
public:
bool divisorGame(int N) {
if(N%2==0)
return true;
else
return false;
}
};
5030. 节点与其祖先之间的最大差值
给定二叉树的根节点 root
,找出存在于不同节点 A
和 B
之间的最大值 V
,其中 V = |A.val - B.val|
,且 A
是 B
的祖先。
(如果 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 得出。
提示:
- 树中的节点数在
2
到5000
之间。 - 每个节点的值介于
0
到100000
之间。
思路:在遍历的过程记录最大最小值即可
/**
* 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 maxres=0;
int maxAncestorDiff(TreeNode* root) {
dfs(root,100000,0);
return maxres;
}
void dfs(TreeNode* root,int minnum,int maxnum)
{
if(root->left==NULL&&root->right==NULL)
{
minnum=min(minnum,root->val);
maxnum=max(maxnum,root->val);
maxres=max(maxres,maxnum-minnum);
return;
}
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);
}
};
5025. 最长等差数列
给定一个整数数组 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]。
示例 3:
输入:[20,1,15,3,10,5,8] 输出:4 解释: 最长的等差子序列是 [20,15,10,5]。
提示:
2 <= A.length <= 2000
0 <= A[i] <= 10000
思路:动态规划dp[d][i]表示以i为结尾公差为d的数列最大长度,我当时用的暴力法。
class Solution {
public:
int longestArithSeqLength(vector<int>& A) {
int maxlen=2;
for(int i=0;i<A.size()-1;i++)
{
for(int j=i+1;j<A.size();j++)
{
int dc=A[j]-A[i];
int count=2;
int k=j+1;
int pre=j;
while(k<A.size())
{
if(A[k]-A[pre]==dc)
{
count++;
pre=k;
}
k++;
}
if(count>maxlen)
maxlen=count;
}
}
return maxlen;
}
};
5031. 从先序遍历还原二叉树
显示英文描述
- 用户通过次数101
- 用户尝试次数110
- 通过次数104
- 提交次数181
- 题目难度Hard
我们从二叉树的根节点 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]
提示:
- 原始树中的节点数介于
1
和1000
之间。 - 每个节点的值介于
1
和10 ^ 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:
TreeNode* recoverFromPreorder(string S) {
stack<TreeNode*> s;
int i=0;
while(i<S.size())
{
int depth=0,temp=0;
while(i<S.size()&&S[i]=='-')
{
depth++;
i++;
}
while(i<S.size()&&S[i]!='-')
{
temp=temp*10+(S[i]-'0');
i++;
}
while(s.size()>depth)
s.pop();
TreeNode* node=new TreeNode(temp);
if(!s.empty()&&s.top()->left==NULL)
s.top()->left=node;
else if(!s.empty())
s.top()->right=node;
s.push(node);
}
while(s.size()!=1)
s.pop();
return s.top();
}
};