1118. Number of Days in a Month
有一个比较容易记忆的算法:先判断是不是世纪年(能否被100整除),如果是,则用前两位去整除4,如果有余数就是平年,如果余数为0则为闰年。对于不是世纪年的年份,用后两位去整除4,如果余数不为0,则为平年,余数为0则为闰年。
class Solution {
public int numberOfDays(int Y, int M) {
int[][] days={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}};//平年28天,闰年29天
if(Y%100==0)
{
int tmp=Y/100;
if((tmp%4)==0)
{
System.out.println("haha");
return days[1][M-1];
}
else
return days[0][M-1];
}
else if((Y%100%4)==0)
{
System.out.println("xixi");
return days[1][M-1];
}
else
return days[0][M-1];
}
}
1119. Remove Vowels from a String
class Solution {
public String removeVowels(String S) {
StringBuilder sb=new StringBuilder();
for(int i=0;i<S.length();i++){
char c=S.charAt(i);
if(c=='a' || c=='e'|| c=='i'||c=='o'||c=='u')
continue;
sb.append(c);
}
return sb.toString();
}
}
1120. Maximum Average Subtree
在进行递归的“递”时,需要记录以当前节点为根节点的子树的节点数量,这里使用一个HashMap来存储。而计算当前节点的均值需要左右子树的均值和子树节点数量。难度不是很大。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public static HashMap<TreeNode,Integer> map;
public static double ans;
public static double maximumAverageSubtree(TreeNode root) {
map=new HashMap<>();
ans=0;
recursive(root);
return ans;
}
public static double recursive(TreeNode root){
if(root.left==null && root.right==null){
map.put(root,1);
ans=Math.max(ans,(double)root.val);
return (double) root.val;
}
double leftVal=0,rightVal=0;
if(root.left!=null)
leftVal=recursive(root.left);
if(root.right!=null)
rightVal=recursive(root.right);
double sum=leftVal*Double.valueOf(map.getOrDefault(root.left,0))+rightVal*Double.valueOf(map.getOrDefault(root.right,0))+root.val;
map.put(root,map.getOrDefault(root.left,0)+map.getOrDefault(root.right,0)+1);
double avg=sum/map.get(root);
ans=Math.max(ans,avg);
return avg;
}
}
1121. Divide Array Into Increasing Sequences
class Solution {
public boolean canDivideIntoSubsequences(int[] nums, int K) {
HashMap<Integer,Integer> count=new HashMap<>();
for(int i:nums)
count.put(i,count.getOrDefault(i,0)+1);
int index=Integer.MAX_VALUE,c=0;
for(int i:count.keySet()){
if(count.get(i)>c){
index=i;
c=count.get(i);
}
}
return K*c<=nums.length;
}
}
class Solution {
public int[] relativeSortArray(int[] arr1, int[] arr2) {
int[] ans=new int[arr1.length];
HashMap<Integer,Integer> co=new HashMap<>();
for(int i=0;i<arr1.length;i++)
co.put(arr1[i],co.getOrDefault(arr1[i],0)+1);
int j=0;
for(int i=0;i<arr2.length;i++){
int times=co.get(arr2[i]);
for(int n=0;n<times;n++)
{
ans[j++]=arr2[i];
}
co.remove(arr2[i]);
}
System.out.println(j);
int n=j;
for(Integer key:co.keySet()){
int t=co.get(key);
while(t>0)
{
ans[n++]=key;
t--;
}
}
Arrays.sort(ans,j,n);
return ans;
}
}
1123. Lowest Common Ancestor of Deepest Leaves
关键点:对于最深的叶子的最浅的公共祖先,当第一个出现的某个节点的左右子树等高时,该节点就是最深的叶子的最浅的公共祖先。如果不等高,该公共祖先必然在较高的子树上。
算法一:该算法每到一个新节点就需要重新计算高度,而没有利用已有的左右子树的高度,时间复杂度为O(n^2)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lcaDeepestLeaves(TreeNode node) {
if(node==null || height(node.left)==height(node.right))
return node;
return lcaDeepestLeaves(height(node.left)>height(node.right)?node.left:node.right);
}
public static int height(TreeNode node){
if(node==null)
return 0;
return Math.max(height(node.left),height(node.right))+1;
}
}
算法二:将已有的左右子树的高度缓存下来,类似于1120. Maximum Average Subtree的思想,这样时间复杂度会下降到O(n)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public static HashMap<TreeNode,Integer> map=new HashMap<>();
public TreeNode lcaDeepestLeaves(TreeNode node) {
if(node==null || height(node.left)==height(node.right))
return node;
return lcaDeepestLeaves(height(node.left)>height(node.right)?node.left:node.right);
}
public static int height(TreeNode node){
if(node==null)
return 0;
if(map.containsKey(node))
return map.get(node);
map.put(node,Math.max(height(node.left),height(node.right))+1);
return map.get(node);
}
}
算法三:与算法二类似的思想,通过定义带高度的节点类型将左右子节点的高度缓存下来
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public class Node{
TreeNode node;
int height;
public Node(TreeNode node,int height){
this.node=node;
this.height=height;
}
public Node(int height){
this(null,height);
}
}
public TreeNode lcaDeepestLeaves(TreeNode node) {
return recursive(node).node;
}
public Node recursive(TreeNode node){
if(node==null)
return new Node(0);
Node left=recursive(node.left);
Node right=recursive(node.right);
int cur_height=Math.max(left.height,right.height)+1;
if(left.height>right.height)
return new Node(left.node,cur_height);
else if(left.height<right.height)
return new Node(right.node,cur_height);
else
return new Node(node,cur_height);
}
}
1124. Longest Well-Performing Interval
分别计算劳累天数和不劳累天数的前缀和,再用暴力方法搜索。
算法一:前缀和+暴力
class Solution {
public int longestWPI(int[] hours) {
int n=hours.length;
int[] record1=new int[n+1];
int[] record2=new int[n+1];
/*
1 2 3 4 5 6 7
1 2 2 2 2 2 3
0 0 1 2 3 4 4
*/
for(int i=1;i<=n;i++){
if(hours[i-1]>8)
{
record1[i]=record1[i-1]+1;
record2[i]=record2[i-1];
}
else
{
record2[i]=record2[i-1]+1;
record1[i]=record1[i-1];
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j>0;j--){
if(record1[i]-record1[j-1]>record2[i]-record2[j-1])
ans=Math.max(ans,i-j+1);
}
}
return ans;
}
}
算法二:
class Solution {
public int longestWPI(int[] hours) {
HashMap<Integer,Integer> map=new HashMap<>();
int sum=0,ans=0;
for(int i=0;i<hours.length;i++){
sum=hours[i]>8?sum+1:sum-1;
if(sum>0)
ans=i+1;
else
{
if(map.containsKey(sum-1))
ans=Math.max(ans,i-map.get(sum-1));
}
map.putIfAbsent(sum,i);
}
return ans;
}
}