【leetcode】Weekly Contest 94

  题目不难,被第二题卡了半个多小时QAQ,另一个就是以后能用Hashmap和Hashset的绝不遍历。

1. Leaf-Similar Trees

  dfs、层次遍历把叶子节点遍历然后对比即可,只要是先遍历左节点后遍历右节点就行。

 1 class Solution {
 2     public boolean leafSimilar(TreeNode root1, TreeNode root2) {
 3         ArrayList<Integer> res1 = new ArrayList<>();
 4         ArrayList<Integer> res2 = new ArrayList<>();
 5         getLeaf(root1, res1);
 6         getLeaf(root2, res2);
 7         boolean equal = true;
 8         if(res1.size() == res2.size()){//叶子节点数量都不一样就不可能一样
 9             int i;
10             for(i = 0;i<res1.size();i++){
11                 if(res1.get(i) != res2.get(i)){
12                     equal = false;
13                     break;
14                 }
15             }
16         }
17         return equal;
18     }
19     
20     void getLeaf(TreeNode root,ArrayList<Integer> res){//先序遍历获得所有叶子节点
21         if(root == null){
22             return ;
23         }
24         if(root.left == null && root.right ==null){
25             res.add(root.val);
26         }
27         getLeaf(root.left, res);
28         getLeaf(root.right, res);
29     }
30 }

874. Walking Robot Simulation

  被这题卡了好久,一开始想写的是判断起始点到末尾点中间是否有障碍物,前进的终点位置是最近的那个障碍物前一个位置,后来意识到前进的距离最多是9,直接一个点一个点判断就好了,这样可以直接用Hashset找是否有那个点。

 1     public static int robotSim(int[] commands, int[][] obstacles) {
 2         int[][] dir = {{0,1},{1,0},{0,-1},{-1,0}};
 3         int nowdir = 0;//当前方向
 4         int x = 0,y = 0;//记录当前位置
 5         int max = 0;
 6         int nx,ny;//下一个位置
 7         Set<Long> obstacleSet = new HashSet();
 8         for (int[] obstacle: obstacles) {
 9             long ox = (long) obstacle[0];
10             long oy = (long) obstacle[1];
11             obstacleSet.add((ox << 16) + oy);//前16位记录x的位置,后16位记录y的位置
12         }
13         
14         for(int i = 0;i<commands.length;i++){
15             if(commands[i] == -1){
16                 nowdir = (nowdir+1)%4;
17             }else if (commands[i] == -2) {
18                 nowdir = (nowdir-1+4)%4;
19             }else {
20                 for (int k = 0; k < commands[i]; ++k) {
21                     nx = x + dir[nowdir][0];
22                     ny = y + dir[nowdir][1];
23                     long code = (((long) nx) << 16) + ((long) ny );
24                     if (!obstacleSet.contains(code)) {
25                         x = nx;
26                         y = ny;
27                         max = Math.max(max, x*x + y*y);
28                     }
29                 }
30             }
31         }
32         return max;
33     }

875. Koko Eating Bananas

  第三题不难,二分查找K的值(1-10^9),每次判断时间是否小于H即可,时间复杂度o(10^4*log10^9)。

 1 class Solution {
 2     public int minEatingSpeed(int[] piles, int H) {
 3         int up = 0;
 4         for (int i : piles) {//记录最大的数量,每小时吃的肯定不需要大于这个数量
 5             up = Math.max(up, i);
 6         }
 7         return find(piles,H,1,up);
 8     }
 9     
10     static int find(int[] piles, int H,int min,int max){//二分搜索
11         if(min == max){
12             return min;
13         }else{
14             int mid = (min+max)/2;
15             // System.out.println(min +" "+ max+" "+mid);
16             if(eatAll(piles, H, mid)){//能吃完,就尝试更小的(当然mid也可能是所求值)
17                 return find(piles, H, min, mid);
18             }else {//吃不完,就每小时吃多点
19                 return find(piles, H, mid+1, max);
20             }
21         }
22     }
23     
24     static boolean eatAll(int[] piles,int H,int K){
25         int need = 0;
26         for (int i : piles) {
27             need+=(i/K)+((i%K)==0?0:1);
28         }
29         return need<=H;
30     }
31 }

873. Length of Longest Fibonacci Subsequence

  这题思路对了,用二位数组dp[i][j]记录以A[i]为倒数第二个点,A[j]为最后一个点的最大斐波那契数列长度,o(n^2)遍历这个二维数组填充数据,再遍历一次取得结果即可。

 1 class Solution {
 2     public int lenLongestFibSubseq(int[] A) {
 3         int dp[][] = new int[A.length][A.length];
 4         HashMap<Integer, Integer> index = new HashMap<>();//记录数组值的下标
 5         for(int i = 0;i<A.length;i++){
 6             index.put(A[i], i);
 7         }
 8         for(int i = 2;i<A.length;i++){
 9             for(int j = 0;j<i;j++){
10                 Integer k = index.get(A[i] - A[j]);//查看是否存在需要的值
11                 if(k!=null && k<j){
12                     dp[i][j] = Math.max(dp[i][j], dp[j][k]+1);
13                 }
14             }
15         }
16         int res = 0;
17         for (int[] is : dp) {
18             for (int i : is) {
19                 res = Math.max(res, i);
20             }
21         }
22         return res==0?0:res+2;
23     }
24 }

  一开始没用Hashmap记录,因此需要第三个循环搜索是否存在需要的值,然后就tle惹,用Hashmap降了一个时间复杂度。

  本次题目都不是特别难,不过还是仰望那些20分钟AK的大佬(我看题目的时间可能都不止20min QAQ)。

猜你喜欢

转载自www.cnblogs.com/zzzdp/p/9351414.html