1. 程式人生 > >【leetcode】Weekly Contest 94

【leetcode】Weekly Contest 94

先序 class mine man cci false 節點 技術分享 分享圖片

  題目不難,被第二題卡了半個多小時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)。

【leetcode】Weekly Contest 94