【leetcode】Weekly Contest 94
阿新 • • 發佈:2018-07-22
先序 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 = newArrayList<>(); 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)){ 12equal = 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