📣 VIP通行证夏日特惠 限时立减$68
楼主: AChris
跳转到指定楼层
上一主题 下一主题
收起左侧

刷题skill+编程cultivation+记录

🔗
 楼主| AChris 2019-3-7 03:54:45 | 只看该作者
全局:
03/06/2019 Day29

Leetcode 160. Intersection of Two Linked Lists
Importance【4】

解题思路:
本题主要有两种解法。
a ----> |
           ------->c
b ----> |
第一种:
两个指针,分别从headA 和headB开始,路线分别是 a ->c -> b 和  b- > c - > a。这样可以保证两个指针在c开头的地方相遇。

第二种:
首先求出两个list长度,然后通过截取 list A 和 list B 的头部 让他们成为长度相同的 list。然后再从他们头部移动两个指针直到他们相等位置,他们相遇的位置便是 c 的头部。



  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. *     int val;
  5. *     ListNode next;
  6. *     ListNode(int x) {
  7. *         val = x;
  8. *         next = null;
  9. *     }
  10. * }
  11. */
  12. public class Solution {
  13.     // method1:
  14.     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  15.         // time: O(n) 99.64%
  16.         // space: O(1) 58.37%
  17.         if (headA == null || headB == null) return null;
  18.         ListNode a = headA, b = headB;
  19.         while (a != b) {
  20.             a = a == null? headB : a.next;
  21.             b = b == null? headA : b.next;
  22.         }
  23.         return a;
  24.     }
  25.    
  26. //     // method2:
  27. //     public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  28. //         // time: O(n) 99.64%
  29. //         // space: O(1) 6.99%
  30. //         if (headA == null || headB == null) return null;
  31. //         int lenA = len(headA), lenB = len(headB);
  32. //         if (lenA > lenB) {
  33. //             while (lenA != lenB) {
  34. //                 headA = headA.next;
  35. //                 lenA--;
  36. //             }
  37. //         } else {
  38. //             while (lenA != lenB) {
  39. //                 headB = headB.next;
  40. //                 lenB--;
  41. //             }
  42. //         }
  43. //         while (headA != headB) {
  44. //             headA = headA.next;
  45. //             headB = headB.next;
  46. //         }
  47. //         return headA;
  48. //     }
  49.    
  50. //     private int len(ListNode head) {
  51. //         int length = 0;
  52. //         while (head.next != null) {
  53. //             head = head.next;
  54. //             length++;
  55. //         }
  56. //         return length;
  57. //     }
  58. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-9 03:56:18 | 只看该作者
全局:

03/07/2019 Day30

Leetcode 169. Majority Element
Importance【4】

解题思路:
本题有三种解法
1. 摩尔投票法。非常巧妙的一个算法。
首先,如果真存在一个元素是majority element的话,他数量一定要比其他元素的数量至少多1或2个。所以,我们就设置一个count,一个candidate。count负责抵消,是candidate的话+1,不是的话-1,如果count为0以后,下一次就选用新的candidate。因为反正majority element数量要多,所以,一定可以最后找到的。
顺便说一下,本题有一个假设,是majority element 一定存在。如果没有这个假设的话,需要在判断一下candidate是不是majority candidate,如果是的话,就返回。不是的话,说明不存在。

2. 先sort, 然后第 length / 2 + 1个元素,也就是index为length / 2的元素就是要找的元素。

4.利用map一个一个数。



  1. class Solution {
  2.    
  3.     // method 1: (Moore Voting Algorithm)
  4.     // [url]https://www.youtube.com/watch?v=zOyOwDEF1Rc[/url]
  5.     public int majorityElement(int[] nums) {
  6.         // time: O(n) 99.43%
  7.         // space: O(1) 63.46%
  8.         int count = 0;
  9.         int candidate = -1;
  10.         for (int num : nums) {
  11.             if (count == 0) {
  12.                 candidate = num;
  13.                 count++;
  14.             } else {
  15.                 if (num == candidate) count++;
  16.                 else count--;
  17.             }
  18.         }
  19.         
  20.         // // step 2:
  21.         // // if we do not have the assumption that the majority element always exist, we need this step to make sure the candidate is the majority element
  22.         // // e.g. 2,7,2,1,9 gives us 9 as candidate which is not he majority element
  23.         // count = 0;
  24.         // for (int num : nums) {
  25.         //     if (num == candidate) count++;
  26.         // }
  27.         // if (count <= nums.length / 2) candidate = -1;
  28.         return candidate;
  29.     }
  30.    
  31. //     // method 2:
  32. //     public int majorityElement(int[] nums) {
  33. //         // time: O(nlogn) 99.43%
  34. //         // space: O(1) 50.47%
  35.         
  36. //         // 10 -> 6th element -> nums[5]
  37. //         // 9 -> 5th element -> nums[4]
  38. //         Arrays.sort(nums);
  39. //         return nums[nums.length / 2];
  40. //     }
  41.    
  42.    
  43. //     // method 3:
  44. //     public int majorityElement(int[] nums) {
  45. //         // time: O(n) 27.18%
  46. //         // space: O(n) 8.82%
  47. //         Map<Integer, Integer> map = new HashMap<>();
  48. //         int res = -1;
  49. //         for (int num : nums) {
  50. //             if (map.containsKey(num)) {
  51. //                 map.put(num, map.get(num) + 1);
  52. //             } else {
  53. //                 map.put(num, 1);
  54. //             }
  55.             
  56. //             if (map.get(num) > nums.length / 2) res = num;
  57. //         }
  58. //         return res;
  59. //     }
  60. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-9 05:16:15 | 只看该作者
全局:
03/08/2019 Day31

Leetcode 200. Number of Islands
Importance【5】

解题思路:
这题主要是 暴力解决+DFS/BFS。
具体来说。暴力解决是指,遍历矩阵中的每一个点,看是否为1。然后对每一个点用 DFS/BFS 来搜索该点相邻的点,并将它们设置为其他数,表示这个岛屿已经被发现了。

设置成的数,可以是0,这样最快,最省空间,但不可以将grid回复到原来的样子。
如果要将 grid 在 count 完岛屿之后,恢复到原来的样子,可以将设置成的数变成是1、2然后在搜索之后进行恢复。


  1. class Solution {
  2.    
  3.     // method 1: DFS
  4.     public int numIslands(char[][] grid) {
  5.         // time: O(m*n) 99.99%
  6.         // space: O(m*n) 63.72% since the max depth of the dfs tree is m*n
  7.         if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) return 0;
  8.         int rowNum = grid.length;
  9.         int colNum = grid[0].length;
  10.         int res = 0;
  11.         for (int i = 0; i < rowNum; i++) {
  12.             for (int j = 0; j < colNum; j++) {
  13.                 if (grid[i][j] == '1') {
  14.                     dfs(grid, i, j, rowNum, colNum);
  15.                     res++;
  16.                 }
  17.             }
  18.         }
  19.         return res;
  20.     }
  21.    
  22.     private void dfs(char[][] grid, int i, int j, int rowNum, int colNum) {
  23.         if (i < 0 || i >= rowNum || j < 0 || j >= colNum || grid[i][j] == '0') return;
  24.         // if we do not want to restore the original graph, we can use 0
  25.         // if we want to restore the original graph, we should use another number except from 0
  26.         grid[i][j] = '0';
  27.         dfs(grid, i+1, j, rowNum, colNum);
  28.         dfs(grid, i-1, j, rowNum, colNum);
  29.         dfs(grid, i, j+1, rowNum, colNum);
  30.         dfs(grid, i, j-1, rowNum, colNum);
  31.         return;
  32.     }
  33.    
  34. //     // method2 : BFS
  35. //     class Coordinate {
  36. //         int x;
  37. //         int y;
  38. //         public Coordinate (int x, int y) {
  39. //             this.x = x;
  40. //             this.y = y;
  41. //         }
  42. //     }
  43.    
  44. //     public int numIslands(char[][] grid) {
  45. //         // time: O(m*n) 9.68%
  46. //         // space: O(m*n) 9.02%
  47. //         if (grid == null || grid.length == 0 || grid[0] == null || grid[0].length == 0) return 0;
  48. //         int rowNum = grid.length;
  49. //         int colNum = grid[0].length;
  50. //         int res = 0;
  51. //         Queue<Coordinate> queue = new LinkedList<> ();
  52. //         for (int i = 0; i < rowNum; i++) {
  53. //             for (int j = 0; j < colNum; j++) {
  54. //                 if (grid[i][j] == '1') {
  55. //                     // Initialize the BFS
  56. //                     queue.add(new Coordinate(i, j));
  57. //                     // use the BFS to set all num in this island to be 0
  58. //                     while (!queue.isEmpty()) {
  59. //                         Coordinate cur = queue.poll();
  60. //                         int x = cur.x;
  61. //                         int y = cur.y;
  62. //                         if (x < 0 || x >= rowNum || y < 0 || y >= colNum || grid[x][y] == '0') {
  63. //                             continue;
  64. //                         } else {
  65. //                             grid[x][y] = '0';
  66. //                             queue.add(new Coordinate(x+1, y));
  67. //                             queue.add(new Coordinate(x-1, y));
  68. //                             queue.add(new Coordinate(x, y+1));
  69. //                             queue.add(new Coordinate(x, y-1));
  70. //                         }
  71. //                     }
  72. //                     res++;
  73. //                 }
  74. //             }
  75. //         }
  76. //         return res;
  77. //     }
  78.    
  79. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-10 05:25:43 | 只看该作者
全局:

03/09/2019 Day32

Leetcode 200. Number of Islands
Importance【4】

解题思路:典型的动态规划问题
两种方法,
第一种,设置两个变量,分别是 rob, notrob,代表抢和不抢当前节点所能得到的钱,注意,在每一个循环最开始的时候,还没有更新 rob notrob,此时这两个变量代表对于上一个节点的对应值
第二种,正常设置int[]



  1. class Solution {
  2.     // method 1
  3.     public int rob(int[] nums) {
  4.         // time: O(n) 100%
  5.         // space: O(1) 10.11%
  6.         if (nums == null || nums.length == 0) return 0;
  7.         
  8.         int notrob = 0, rob = 0;
  9.         for (int i = 0; i < nums.length; i++) {
  10.             int currob = notrob + nums[i];
  11.             notrob = Math.max(notrob, rob);
  12.             rob = currob;
  13.         }
  14.         
  15.         return Math.max(notrob, rob);
  16.     }
  17.    
  18. //     // method 2
  19. //     public int rob(int[] nums) {
  20. //         // time: O(n) 100%
  21. //         // space: O(n) 12.74%
  22. //         if (nums == null || nums.length == 0) return 0;
  23. //         if (nums.length == 1) return nums[0];
  24.         
  25. //         int[] res = new int[nums.length];
  26. //         res[0] = nums[0];
  27. //         res[1] = Math.max(nums[0], nums[1]);
  28. //         for (int i = 2; i < nums.length; i++) {
  29. //             res[i] = Math.max(res[i - 2] +  nums[i], res[i - 1]);
  30. //         }
  31.         
  32. //         return res[nums.length - 1];
  33. //     }
  34. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-11 10:54:54 | 只看该作者
全局:


03/10/2019 Day33

Leetcode 200. Number of Islands
Importance【4】

解题思路:
一道挺有意思的题目。不难,但挺有启发的。

基本思路就是,把现在数组一个一个设置成想要的样子。
设置一个指针 toBeSet。
首先遍历所有的数,然后遇见不为 0 的数就把 toBeSet 的位置的数设置成那个数,然后把toBeSet。
因为 #(设置的数) <= 遇到的数,所以不会跳过的数只会是0,不会漏掉不是0的数。
然后,遍历一遍之后,把  toBeSet 以及之后的数设置成 0




  1. class Solution {
  2.     public void moveZeroes(int[] nums) {
  3.         // time: O(n) 100%
  4.         // space: O(1) 95.01%
  5.         if (nums == null || nums.length == 0) return;
  6.         
  7.         int toBeSet = 0;
  8.         for (int num : nums) {
  9.             if (num != 0) nums[toBeSet++] = num;
  10.         }
  11.         while (toBeSet < nums.length) nums[toBeSet++] = 0;
  12.         return;
  13.     }
  14. }
复制代码

补充内容 (2019-3-11 10:55):
题目更正:LeetCode 283. Move Zeroes
回复

使用道具 举报

🔗
 楼主| AChris 2019-4-1 09:31:14 | 只看该作者
全局:
03/29/2019 Day34
LeetCode 322. Coin Change
Importantce【5】

前段时间在忙离散优化的考试,真的超级难,所以一段时间没有刷,现在继续!

解题思路:
主要是利用dynamic programming。
关键在于定义 f[i][j] :用coin i, i+1, i+2,....得到 数量是 j 的钱的最少的硬币数量。
base case主要是 f[n][0] = 0, f[n][1/2/3/...] = inf

方法一:从第n行算第n-1行
方法二:对方法一优化,利用第n行算第n-1行的初始值,再利用n-1行之间的关系算最优解

  1. class Solution {
  2. //     // method1:
  3. //     public int coinChange(int[] coins, int amount) {
  4. //         // time: O(n * m * m) 5.03%
  5. //         // space: O(n * m) 84.68%
  6.         
  7. //         // f[i][j]: min # of coins to use from [i, i+1, i+2, ...] to get value j
  8. //         // base case: f[n][0] = 0, f[n][j!=0] = inf
  9. //         // induction: f[i][j] = min( f[i+1][j],
  10. //         //                           f[i+1][j - coins[i]] + 1,
  11. //         //                           f[i+1][j - 2 * coins[i]] + 2,
  12. //         //                           f[i+1][j - 3 * coins[i]] + 3,
  13. //         //                           ... )
  14. //         int[][] f = new int[coins.length + 1][amount + 1];
  15. //         Arrays.fill(f[coins.length], Integer.MAX_VALUE);
  16. //         f[coins.length][0] = 0;
  17.         
  18. //         for (int i = coins.length - 1; i >= 0; i--) {
  19. //             for (int j = 0; j <= amount; j++) {
  20. //                 int maxK = j / coins[i];
  21. //                 f[i][j] = f[i+1][j];
  22. //                 for (int k = 1; k <= maxK; k++) {
  23. //                     // CAUTION: cannot use Integer.MAX_VALUE to add with some other number
  24. //                     int prev =  f[i+1][j - k * coins[i]];
  25. //                     if (prev < Integer.MAX_VALUE) {
  26. //                         f[i][j] = Math.min(f[i][j], prev + k);
  27. //                     }
  28. //                 }
  29. //             }
  30. //         }
  31. //         if (f[0][amount] == Integer.MAX_VALUE) return -1;
  32. //         else return f[0][amount];
  33. //     }

  34.    
  35.     // method2:
  36.     public int coinChange(int[] coins, int amount) {
  37.         // time: O(n * m) 90.89%
  38.         // space: O(n * m) 88.04%
  39.         
  40.         // f[i][j]: min # of coins to use from [i, i+1, i+2, ...] to get value j
  41.         // base case: f[n][0] = 0, f[n][j!=0] = inf
  42.         // induction: f[i][j] = min( f[i+1][j],
  43.         //                           f[i+1][j - coins[i]] + 1,
  44.         //                           f[i+1][j - 2 * coins[i]] + 2,
  45.         //                           f[i+1][j - 3 * coins[i]] + 3,
  46.         //                           ... )
  47.         int[][] f = new int[coins.length + 1][amount + 1];
  48.         Arrays.fill(f[coins.length], Integer.MAX_VALUE);
  49.         f[coins.length][0] = 0;
  50.         
  51.         for (int i = coins.length - 1; i >= 0; i--) {
  52.             for (int j = 0; j <= amount; j++) {
  53.                 f[i][j] = f[i + 1][j];
  54.                 if (j >= coins[i]) {
  55.                     int prev = f[i][j - coins[i]];
  56.                     if (prev < Integer.MAX_VALUE) {
  57.                         f[i][j] = Math.min(f[i][j], prev + 1);
  58.                     }
  59.                 }
  60.             }
  61.         }
  62.         if (f[0][amount] == Integer.MAX_VALUE) return -1;
  63.         else return f[0][amount];
  64.     }
  65. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-4-4 08:21:58 | 只看该作者
全局:

04/29/2019 Day35
LeetCode 119. Pascal's Triangle II
Importantce【4】


  1. class Solution {
  2.     public List<Integer> getRow(int rowIndex) {
  3.         // time: O(n) 84.47%
  4.         // space: O(n) 100%
  5.         List<Integer> lastrow = new ArrayList<> ();
  6.         lastrow.add(1);
  7.         for (int i = 1; i <= rowIndex; i++) {
  8.             lastrow = createLayer(lastrow);
  9.         }
  10.         return lastrow;
  11.     }
  12.    
  13.     private List<Integer> createLayer(List<Integer> lastrow) {
  14.         List<Integer> res = new ArrayList<> ();
  15.         res.add(1);
  16.         for (int i = 0; i <= lastrow.size() - 2; i++) {
  17.             int num = lastrow.get(i) + lastrow.get(i+1);
  18.             res.add(num);
  19.         }
  20.         res.add(1);
  21.         lastrow = res;
  22.         return lastrow;
  23.     }
  24. }
复制代码

补充内容 (2019-4-4 08:23):
解题思路: 先生成某一行,然后根据上一行依次产生下一行。

注意,加入通过function(lastrow)把一个 list 传到另一个子函数里面,那么,在子函数里面,各种add、remove的话,可以体现在原函数的lastrow里的

补充内容 (2019-4-4 08:24):
但是,如果lastrow = some_other_row,那么,lastrow这个原函数的lastrow的copy的值被改变了,并不会影响原函数里的lastrow的值。
回复

使用道具 举报

🔗
 楼主| AChris 2019-4-4 23:40:46 | 只看该作者
全局:
04/4/2019 Day36
LeetCode 66. Plus One
Importantce【4】

解题思路:
从后往前依次对digits进行遍历,直到不用进位顺利加1。
如果都需要进位,那么最后重新生成一个数,开头是1,其他全是0。

  1. class Solution {
  2.     public int[] plusOne(int[] digits) {
  3.         // time: O(n) 100%
  4.         // space: O(n) 26.28%
  5.         for (int i = digits.length - 1; i >= 0; i--) {
  6.             if (digits[i] < 9) {
  7.                 digits[i]++;
  8.                 return digits;
  9.             }
  10.             digits[i] = 0;
  11.         }
  12.         int[] newDigits = new int[digits.length + 1];
  13.         newDigits[0] = 1;
  14.         return newDigits;
  15.     }
  16. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-4-6 03:30:33 | 只看该作者
全局:

04/5/2019 Day37
LeetCode 236. Lowest Common Ancestor of a Binary Tree
Importantce【4】

解题思路:
这题的题目中有两个重要的前提条件:
1.所有的node的val都是unique的
2.要找的p和q都一定在p中存在

具体解法是递归。对于每一个node,如果他的subtree下面
如果有 p 就返回p;
如果有q,就返回q;
如果都有,就返回自己。
具体看 https://www.youtube.com/watch?v=13m9ZCB8gjw


  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. *     int val;
  5. *     TreeNode left;
  6. *     TreeNode right;
  7. *     TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11.     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
  12.         // [url]https://www.youtube.com/watch?v=13m9ZCB8gjw[/url]
  13.         // time: O(n) 70.51%
  14.         // space: O(logn) 67.93%
  15.         if (root == null) return null;
  16.         if (root.val == p.val || root.val == q.val) return root;
  17.         
  18.         TreeNode left = lowestCommonAncestor(root.left, p, q);
  19.         TreeNode right = lowestCommonAncestor(root.right, p, q);
  20.         
  21.         if (left != null && right != null) return root;
  22.         if (left == null && right == null) return null;
  23.         return left != null? left : right;
  24.     }
  25. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-4-6 09:03:47 | 只看该作者
全局:


04/6/2019 Day37
LeetCode 572. Subtree of Another Tree
Importantce【4】

解题思路:
这题的关键是将 找是否是subtree的问题转化为是否是same tree的问题,然后,在通过递归来解决是否是 same tree的问题。

  1. /**
  2. * Definition for a binary tree node.
  3. * public class TreeNode {
  4. *     int val;
  5. *     TreeNode left;
  6. *     TreeNode right;
  7. *     TreeNode(int x) { val = x; }
  8. * }
  9. */
  10. class Solution {
  11.     public boolean isSubtree(TreeNode s, TreeNode t) {
  12.         // time: O(n) 99.64%
  13.         // space: O(logn) 90.11%
  14.         if (s == null && t!= null) return false;
  15.         if (sameTree(s, t)) return true;
  16.         return isSubtree(s.left, t) || isSubtree(s.right, t);
  17.     }
  18.    
  19.     private boolean sameTree(TreeNode s, TreeNode t) {
  20.         if (s == null && t == null) return true;
  21.         if (s == null || t == null) return false;
  22.         return s.val == t.val && sameTree(s.left, t.left) && sameTree(s.right, t.right);
  23.     }
  24. }
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表