题目列表:
5024. 除数博弈:
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
- 选出任一 x,满足 0 < x < N 且 N % x == 0 。
- 用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。
示例 1: 输入:2 输出:true 解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2: 输入:3 输出:false 解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
解法一:
分析:
1 的时候爱丽丝必输
2 的时候爱丽丝选择1, 让鲍勃陷入必输的状态, 此状态为必赢状态。
3 的时候爱丽丝 只能选择1, 让鲍勃陷入必赢的状态
4 时候爱丽丝选择2, 让鲍勃选择2, 此状态为必赢状态, 依次类推
假设 a1, a2, a3 ......., an 是的在[1, N) 之间能使N被整除的数字, 那么
dp[i] 值为 bool 表示面临 i 的时候的输赢状况,
则状态转移方程为:
dp[N] = !dp[N - a1] || !dp[a2] || ........ || !dp[an];
class Solution
{
public:
bool divisorGame(int N)
{
vector<bool> dp(N + 1);
dp[1] = false; for(int i = 2; i <= N; ++i)
{
dp[i] = false;
for(int k = 1; k != i; ++k)
{
if(i % k == 0 && !dp[i]) dp[i] = dp[i] || !dp[i - k];
}
} return dp[N];
}
};
解法二:
牛逼克拉斯的解法, 不晓得怎么证明:
class Solution
{
public:
bool divisorGame(int N)
{
return (N % 2 == 0);
}
};
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 之间。
解题思路:
使用先序遍历的方式, 以每个结点为根节点来与其所有子孩子之间进行计算差值, 在此过程当中来计算出最大值是多少,考虑到结点数量可能有点多, 则我们使用迭代的方式来实现先序遍历:
#include <cmath>
class Solution {
public:
int max_val;
int maxAncestorDiff(TreeNode* root)
{
max_val = INT_MIN;
preorder(root);
return max_val;
}
//先序遍历
void preorder(TreeNode *root)
{
stack<TreeNode *> nodes;
if(!root) return;
nodes.push(root);
while(!nodes.empty())
{
auto node = nodes.top(); nodes.pop();
//直接对其左边的孩子进行计算
while(node)
{
caclute(node);
if(node->right) nodes.push(node->right);
node = node->left;
}
}
}
//计算当前结点的值 和 其所有孩子结点的值之间的差值
void caclute(TreeNode *root)
{
stack<TreeNode *> nodes;
if(!root) return;
nodes.push(root);
while(!nodes.empty())
{
auto node = nodes.top(); nodes.pop();
//直接对其左边的孩子进行计算
while(node)
{
max_val = max(max_val, abs(root->val - node->val));
if(node->right) nodes.push(node->right);
node = node->left;
}
}
}
};
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
解法一:
暴力破解。 双重for循环得到顶点对 i , j, 并在 j + 1 , n 之间在寻找以i 和 j 开始等差数列元素即可.
解法二:
动态规划。
以i结尾, 并且 d = i - j 为等差值的序列的长度:
dp[i - j, i] = 2;
dp[i - j , j] = max(dp[i - j, j] + 1, dp[i - j, i]);
class Solution
{
public:
int longestArithSeqLength(vector<int>& A)
{
map<pair<int, int>, int> dp;
int res = 2;
for(int i = 1; i < A.size(); ++i)
{
for(int j = 0; j < i; ++j)
{
dp[{A[i] - A[j], i}] = 2;
dp[{A[i] - A[j], i}] = max(dp[{A[i] - A[j], j}] + 1, dp[{A[i] - A[j], i}]);
res = max(dp[{A[i] - A[j], i}], res);
}
}
return res;
}
};
5031. 从先序遍历还原二叉树
我们从二叉树的根节点 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 之间。
解法:
使用先序遍历的方式, 并标记当前结点的层次, 和递归过程中 标记的 ‘’-‘’的数量 来判断是否构造。
class Solution
{
public:
TreeNode* recoverFromPreorder(string S)
{
int cur = 0, pre_cnt = 0;
return build(S, cur, pre_cnt, 0);
}
TreeNode *build(string &s, int &cur, int &cnt, int level)
{
//当层级别 和 读取 - 数量相等的时候代表能使用此值来进行构建
TreeNode *node = NULL;
if(level == cnt && cur < s.size())
{
//取值, 假设cur定位在数字上面
int val = 0;
for(;cur < s.size() && s[cur] != '-'; ++cur)
{
val = val * 10 + (s[cur] - '0');
}
node = new TreeNode(val);
cnt = 0;
for(;cur < s.size() && s[cur] == '-'; ++cur)
++cnt;
node->left = build(s, cur, cnt, level + 1);
node->right = build(s, cur, cnt, level + 1);
}
return node;
}
};