周赛135
leetcode 1037.有效的回旋镖
解题思路:就是判断三角形的问题,用的斜率方法,坐标抽平行另处理,未优化
public boolean isBoomerang(int[][] points) {
if((points[0][0] == points[1][0] && points[0][1] == points[1][1]) ||
(points[0][0] == points[2][0] && points[0][1] == points[2][1]) ||
(points[1][0] == points[2][0] && points[1][1] == points[2][1]))
return false;
double a = (double)(points[0][0]-points[1][0])==0?Integer.MAX_VALUE:(
(points[0][1]-points[1][1])==0?0:(double)(points[0][0]-points[1][0])/(points[0][1]-points[1][1]));
double b = (points[1][0]-points[2][0])==0?Integer.MAX_VALUE:(
(points[1][1]-points[2][1])==0?0:(double)(points[1][0]-points[2][0])/(points[1][1]-points[2][1]));
if(a == b)
return false;
return true;
}
leetcode 1038. 从二叉搜索树到更大和树
解题思路:反向中序遍历(右子树-根节点-左子树)求和,更新节点值
int sum = 0;
void inorder(TreeNode root) {
if(root.right != null)
inorder(root.right);
root.val+=sum;
sum = root.val;
if(root.left!=null)
inorder(root.left);
}
public TreeNode bstToGst(TreeNode root) {
if(root == null)
return root;
inorder(root);
return root;
}
leetcode 1039. 多边形三角剖分的最低得分
解题思路:和题312戳气球相同解法,题312可能更好理解,原题已给出提示,对于问题A[i]-A[j],选择点k,将问题分解为A[i]-A[k],A[k]-A[j]两个子问题,动态规划求解dp[0][n-1],转移方程:dp[i][i+l] = Min(dp[i][i+l],A[i]*A[k]*A[i+l] + dp[i][k] + dp[k][i+l])
public int minScoreTriangulation(int[] A) {
int len = A.length;
int[][] dp = new int[len][len];
for(int i = 0;i < len - 1;i++){
for(int j = 0;j <= len - 1;j++) {
dp[i][j] = Integer.MAX_VALUE;
}
dp[i][i+1] = 0;
}
for(int l = 2;l < len;l++){
for(int i = 0;i + l < len;i++){
for (int k = i + 1; k < i + l; k++) {
dp[i][i+l] =Math.min(dp[i][i+l],A[i]*A[k]*A[i+l]+dp[i][k]+dp[k][i+l]);
}
}
}
return dp[0][len-1];
}
leetcode 1040. 移动石子直到连续 II
解题思路:对于maximum_moves,只需要考虑第一次移动,因为之后的每次移动我们都能保证剩余位置-1;对于minimum_moves,利用长度为stones.length的滑动窗口,满足窗口内的端点最多,窗口内空余的端点数量即为最小移动次数。特殊情况:窗口内石子连续,边缘有空,则需要移动2次。
public int[] numMovesStonesII(int[] stones) {
Arrays.sort(stones);
int len = stones.length;
int max = stones[len-1] - stones[0] + 1 - len, min = max;
max -= Math.min(stones[len-1] - stones[len-2] - 1,stones[1] - stones[0] - 1);
int j = 0;
for(int i = 0;i < len;i++){
while (j + 1 < len && stones[j+1] - stones[i] < len)
j++;
int mi = len - (j - i + 1);
if(j - i + 1 == len - 1 && stones[j] - stones[i] + 1 == len - 1)
mi = 2;
min = Math.min(mi,min);
}
int[] res = {min,max};
return res;
}