一、LeetCode:515. 在每个树行中找最大值
(1)题目描述
给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
示例1:
输入: root = [1,3,2,5,3,null,9]
输出: [1,3,9]
解释:
1
/ \
3 2
/ \ \
5 3 9
示例2:
输入: root = [1,2,3]
输出: [1,3]
解释:
1
/ \
2 3
示例3:
输入: root = [1]
输出: [1]
示例4:
输入: root = [1,null,2]
输出: [1,2]
解释:
1
\
2
示例5:
输入: root = []
输出: []
(2)题目分析
这道题就是树的按层遍历,找每层最大的数值然后添加入集合中即可.
(3)代码实现
class Solution{
public List<Integer>largestValues(TreeNode root){
List<Integer>res=new ArrayList<>();
if(root==null) return res;
LinkedList<TreeNode>queue=new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int size=queue.size();
int max=queue.getFirst().val;
for(int i=0;i<size;i++){
TreeNode node=queue.removeFirst();
if(node.val>max){
max=node.val;
}
if(node.left!=null){
queue.addLast(node.left);
}
if(node.right!=null){
queue.addLast(node.right);
}
}
res.add(max);
}
return res;
}
}
二、LeetCode:513. 找树左下角的值
(1)问题描述
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:
输入: root = [2,1,3]
输出: 1
示例 2:
输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
(2)问题分析
这道题也是一道按层遍历的题,每次都添加每层的结点,设置一个节点,每次都指向该层的第一个添加的节点,最后返回该节点的值
(3)代码实现
class Solution{
public int findBottomLeftValue(TreeNode root){
LinkedList<TreeNode>queue=new LinkedList<>();
TreeNode pre=root;
queue.add(root);
while(!queue.isEmpty()){
int size=queue.size();
pre=queue.getFirst();
for(int i=0;i<size;i++){
TreeNode node=queue.removeFirst();
if(node.left!=null){
queue.addLast(node.left);
}
if(node.right!=null){
queue.addLast(node.right);
}
}
}
return pre.val;
}
}
三、LeetCode:122. 买卖股票的最佳时机 II
(1)题目描述
给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例 2:
输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
(2)问题分析
这道题用动态规划,使用二位数组dp[i][j],i表示第i天,j表示持有的股票数,当你手里没有股票的时候可能是本身就没有,还可能是手里面有一个股票但是卖出了,当你手里持有股票的时候,可能是本身就持有没有卖,还可能是本身没有当天买入了,所以出现两个动态规划方程。
(3)代码实现
class Solution{
public int maxProfit(int[] prices){
int n=prices.length;
int[][] dp=new int[n][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i<n;i++){
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[n-1][0];
}
}
四、LeetCode:978. 最长湍流子数组
(1)题目描述
当 A 的子数组 A[i], A[i+1], ..., A[j] 满足下列条件时,我们称其为湍流子数组:
若 i <= k < j,当 k 为奇数时, A[k] > A[k+1],且当 k 为偶数时,A[k] < A[k+1];
或 若 i <= k < j,当 k 为偶数时,A[k] > A[k+1] ,且当 k 为奇数时, A[k] < A[k+1]。
也就是说,如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是湍流子数组。
返回 A 的最大湍流子数组的长度。
示例 1:
输入:[9,4,2,10,7,8,8,1,9]
输出:5
解释:(A[1] > A[2] < A[3] > A[4] < A[5])
示例 2:
输入:[4,8,12,16]
输出:2
示例 3:
输入:[100]
输出:1
(2)题目分析
这道题很显然是一道动态规划题,因为数组分为奇数和偶数下标两种,由题解可以看出每个以奇数为下标的数组都大于每个以偶数为下标的数组,或者每个以偶数为下标的数组都大于每个以奇数为下标的数组,所以我们需要用偶数数组+1来表示奇数数组,同样奇数数组+1来表示偶数数组。
(3)代码实现
class Solution{
public int maxTurbulenceSize(int[] arr){
int n=arr.length;
int[][] dp=new int[n][2];
dp[0][0]=dp[0][1]=1;
for(int i=1;i<n;i++){
dp[i][0]=dp[i][1]=1;
if(arr[i-1]>arr[i]){
dp[i][0]=dp[i-1][1]+1;
}else if(arr[i-1]<arr[i]){
dp[i][1]=dp[i-1][0]+1;
}
}
int ret=1;
for(int i=0;i<n;i++){
ret=Math.max(ret,dp[i][0]);
ret=Math.max(ret,dp[i][1]);
}
return ret;
}
}