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;
}
}