462. 最少移动次数使数组元素相等 II【中等题】【每日一题】
思路:【贪心】
每个元素都可以加
1
或者减1
,那么肯定是找出数组元素中的中位数当目标值啊,所有的数都往中位数改变,这样需要的移动数才是最少的,具体证明的话题解和评论区都有不再赘述。直觉告诉我就是排序后向中位数移动。
代码:
class Solution {
public int minMoves2(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
int mid = nums[n / 2],ans = 0;
for (int num : nums) {
ans += Math.abs(num - mid);
}
return ans;
}
}
剑指 Offer II 051. 节点之和最大的路径【困难题】
思路:【递归】
从根节点开始,递归的求出每个节点对 使路径和达到最大 这件事情的贡献值,并在递归求解的过程中更新最大路径和
maxSum
。
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//全局变量 maxSum 表示最大路径和,初值为int下边界
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
//从根节点开始,递归的求出每个节点对使路径和达到最大的贡献值,并在这个过程中更新最大路径和 maxSum
maxGain(root);
//返回 maxSum
return maxSum;
}
public int maxGain(TreeNode node){
//如果当前节点是null,则其贡献值为 0
if (node == null){
return 0;
}
//递归求解当前节点的左子节点的贡献值 并将其与0比较大小,较大者赋值给 leftGain 表示当前节点的左子树能够提供的最大贡献
int leftGain = Math.max(maxGain(node.left),0);
//递归求解当前节点的右子节点的贡献值 并将其与0比较大小,较大者赋值给 rightGain 表示当前节点的右子树能够提供的最大贡献
int rightGain = Math.max(maxGain(node.right),0);
//以当前节点为连接点,能够形成的和最大的路径 的 和 等于 当前节点的值 、 左子树的最大贡献 、 右子树的最大贡献 三者之和
int curPathSum = node.val + leftGain + rightGain;
//如果maxSum需要更新,则将其更新
maxSum = Math.max(maxSum,curPathSum);
//返回当前节点的最大贡献值(即节点值 + 左子树和右子树最大贡献值中较大的那个)
return node.val + Math.max(leftGain,rightGain);
}
}