https://leetcode.com/contest/weekly-contest-132
对应题目:1025-1028
1:博弈问题,后继节点存在一个为败,当前为即为必胜。
public boolean divisorGame(int N) {
boolean[] dp = new boolean[1005];
dp[1] = false;
dp[2] = true;
dp[3] = false;
for (int i = 4; i <= N; i++) {
boolean f = false;
for (int j = 1; j < i; j++) {
if(i % j == 0 && !dp[i - j]) {
f = true;
break;
}
}
dp[i] = f;
}
return dp[N];
}
2:dfs,维护最大值和最小值
int ret = 0;
public int maxAncestorDiff(TreeNode root) {
ret = 0;
dfs(root, root.val, root.val);
return ret;
}
void dfs(TreeNode cur, int max, int min)
{
if(cur == null)return;
ret = Math.max(ret, Math.abs(max-cur.val));
ret = Math.max(ret, Math.abs(min-cur.val));
dfs(cur.left, Math.max(max, cur.val), Math.min(min, cur.val));
dfs(cur.right, Math.max(max, cur.val), Math.min(min, cur.val));
}
3:找到子数组(可以不连续)长度最大的等差数列
dp[i][d]表示以i结尾的公差为d的最大长度: dp[i][d] = dp[j][d] + 1(j < i)
d可能为负数,加个值修正一下。
public int longestArithSeqLength(int[] A) {
int ans = 2;
int n = A.length;
int diff = 10000;
int[][] dp = new int[10010][20010];
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
int d = A[i] - A[j];
int ddiff = d + diff;
if (dp[j][ddiff] == 0) {
dp[i][ddiff] = 2;
} else {
dp[i][ddiff] = dp[j][ddiff] +1;
}
ans = Math.max(ans, dp[i][ddiff]);
}
}
return ans;
}
4:给了一个树的深度遍历,还原树。
按照题意遍历,贴个uwi的代码
public class D {
int pos = 0;
char[] s;
int len = 0;
public TreeNode recoverFromPreorder(String S) {
len = S.length();
s = S.toCharArray();
pos = 0;
return go(0);
}
TreeNode go(int dep) {
int v = 0;
while (pos < len && s[pos] >= '0' && s[pos] <= '9') {
v = v * 10 + (s[pos] - '0');
pos++;
}
TreeNode cur = new TreeNode(v);
if (hasEdge(dep + 1)) {
pos += dep + 1;
cur.left = go(dep + 1);
}
if (hasEdge(dep + 1)) {
pos += dep + 1;
cur.right = go(dep + 1);
}
return cur;
}
boolean hasEdge(int d) {
if (pos + d > len - 1) return false;
for (int i = pos; i < pos + d; i++) {
if (s[i] != '-') return false;
}
return s[pos + d] != '-';
}
}