Leetcode刷题 2021.01.17
Leetcode1605 给定行和列的和求可行矩阵
给你两个非负整数数组 rowSum 和 colSum ,其中 rowSum[i] 是二维矩阵中第 i 行元素的和, colSum[j] 是第 j 列元素的和。换言之你不知道矩阵里的每个元素,但是你知道每一行和每一列的和。
请找到大小为 rowSum.length x colSum.length 的任意 非负整数 矩阵,且该矩阵满足 rowSum 和 colSum 的要求。
请你返回任意一个满足题目要求的二维矩阵,题目保证存在 至少一个 可行矩阵。
这道题一开始没什么思路,因为要随便返回一个矩阵,以为是回溯,但想了想时间复杂度太高了,不可能。既然不可能是真的随便返回就一定有技巧,所以想到贪心的做。每一次让一格满足该行或者该列的需求就行了。比如rowSum = [3,8], colSum = [4,7],那么在(0, 0)的位置填入3,那么这一行的要求就满足了,往下一行填。注意下一行要满足列的要求,即第一列只能填4-3 = 1了。所以在(1,0)填1,然后填第二列即可。编码也比较短,O(MN)的复杂度。
class Solution {
public int[][] restoreMatrix(int[] rowSum, int[] colSum) {
int m = rowSum.length, n = colSum.length;
//结果矩阵
int[][] res = new int[m][n];
int col = 0, row = 0;
while (col < n && row < m){
//贪心地满足较小地条件
if (rowSum[row] <= colSum[col]){
res[row][col] = rowSum[row];
//行满足了,列要减掉
colSum[col] = colSum[col] - rowSum[row];
//继续下一行
row++;
//列就是行的镜像
}else{
res[row][col] = colSum[col];
rowSum[row] = rowSum[row] - colSum[col];
col++;
}
}
return res;
}
}
Leetcode1451 重新排列句子中的单词
在一个 XY 坐标系中有一些点,我们用数组 coordinates 来分别记录它们的坐标,其中 coordinates[i] = [x, y] 表示横坐标为 x、纵坐标为 y 的点。
请你来判断,这些点是否在该坐标系中属于同一条直线上,是则返回 true,否则请返回 false。
每天晚上做每日一题,想着赶着去睡觉,代码都写的比较乱。思路还是简单的,但是这种判断共线的方法要特殊判断除数不为0的情况。感觉不是很优雅,看了题解里用共线,行列式来做,比较简洁一些。不过面试一般不会出这种题吧。
class Solution {
public boolean checkStraightLine(int[][] coordinates) {
int[] prev = coordinates[1];
double prevValue = 0;
if(coordinates[0][1] != coordinates[1][1]){
prevValue = (double)(coordinates[0][0] - coordinates[1][0]) / (double)(coordinates[0][1] - coordinates[1][1]);
}else{
prevValue = coordinates[0][1];
}
for(int i = 2; i < coordinates.length; i++){
int x = coordinates[i][0], y = coordinates[i][1];
double temp = 0;
if(coordinates[0][1] != coordinates[1][1]){
temp = (double)(x - prev[0]) / (double)(y - prev[1]);
}else{
temp = y;
}
if (temp != prevValue){
return false;
}
prev = coordinates[i];
}
return true;
}
}
Leetcode1325 删除给定值的叶子节点
给你一棵以 root 为根的二叉树和一个整数 target ,请你删除所有值为 target 的 叶子节点 。
注意,一旦删除值为 target 的叶子节点,它的父节点就可能变成叶子节点;如果新叶子节点的值恰好也是 target ,那么这个节点也应该被删除。
也就是说,你需要重复此过程直到不能继续删除。
又是简单的二叉树题,删除给定值的叶子节点。返回一个布尔值,如果是给定值而且是叶子节点的话,就返回true,然后由上一层的节点删除。自底向上递归,最后主函数特判一下root节点就好了。
class Solution {
public TreeNode removeLeafNodes(TreeNode root, int target) {
boolean flag = helper(root, target);
return flag == true ? null : root;
}
private boolean helper(TreeNode root, int target){
if (root == null) return false;
boolean l = helper(root.left, target);
boolean r = helper(root.right, target);
if (l) root.left = root.left.left;
if (r) root.right = root.right.right;
return root.val == target && root.left == null && root.right == null;
}
}