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

刷题skill+编程cultivation+记录

🔗
 楼主| AChris 2019-3-1 09:31:52 | 只看该作者
全局:
02/28/2019 Day23

Leetcode 121. Best Time to Buy and Sell Stock
Importance【4】

解题思路:
做一次遍历就好了,注意在遍历price的过程中,随时更新price的最小值和profit


  1. class Solution {
  2.     public int maxProfit(int[] prices) {
  3.         // time: O(n) 100%
  4.         // space: O(1) 97.21%
  5.         if (prices.length < 2) return 0;
  6.         int min = prices[0];
  7.         int profit = 0;
  8.         for (int price: prices) {
  9.             min = Math.min(min, price);
  10.             profit = Math.max(profit, price - min);
  11.         }
  12.         return profit;
  13.     }
  14. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-1 09:54:24 | 只看该作者
全局:

02/28/2019 Day23

Leetcode 136. Single Number
Importance【4】

解题思路:
这题主要是可以运用 位运算 - 异或 - XOR 来计算,所以很巧妙。
异或有这样的性质:
(1) a ^ b = b ^ a
(2)a ^ b ^ b = a 如果一个数出现两次,和res运算,那么不影响结果
(3)0 ^ a = a 如果一个数只出现一次,和0运算,结果就是那个书本身



  1. class Solution {
  2.     // method1:
  3.     public int singleNumber(int[] nums) {
  4.         // time: O(n)
  5.         // space: O(1)
  6.         
  7.         // XOR ^: same return 0 else 1
  8.         // (1) XOR is commutative: a ^ b = b ^ a
  9.         // (2) So, if a number appear twice, it makes no change to the result.
  10.         //     On the contrary, if a number is unique, 0 ^ a = a
  11.         int res = 0;
  12.         for (int num: nums) {
  13.             res ^= num;
  14.         }
  15.         return res;
  16.         
  17.     }
  18.    
  19.     // // method2:
  20.     // public int singleNumber(int[] nums) {
  21.     //     // time: O(n) 35.82%
  22.     //     // space: O(n) 30.99%
  23.     //     Set<Integer> hs = new HashSet<> ();
  24.     //     for (int num: nums) {
  25.     //         if (hs.contains(num)) hs.remove(num);
  26.     //         else hs.add(num);
  27.     //     }
  28.     //     return Integer.parseInt(hs.toArray()[0].toString());
  29.     // }
  30. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-2 03:16:08 | 只看该作者
全局:


03/01/2019 Day24

Leetcode 137. Single Number II
Importance【4】

解题思路:
还是一道很有trick的题。有两种方法,用HashMap的话就是暴力解决,没啥好说的。

第二种方法是用bitwise operation,比较方便,也很tricky。
主要是用一个ones,一个twos,表示第一次第二次遇到某个num。
                    ones twos
没有遇到          0      0
第一次遇到       1      0
第二次遇到       0      1
第三次遇到       0      0

具体的运算主要还是使用异或XOR,但是要注意。在第一次遇到的时候,ones赋值,twos不赋值,也就是twos不能和ones一样。
在第三次遇到的时候,ones不赋值,twos赋值,也就是ones不能和上一个twos一样。
为了不赋值,可以用 (ones ^ num) & ~b 来使得结果的数不是b。因为,b & ~b = 0

  1. class Solution {
  2.     public int singleNumber(int[] nums) {
  3.         if (nums == null || nums.length == 0) return -1;
  4.         
  5.         // time: O(n) 100%
  6.         // space: O(1) 86.53%
  7.         
  8.         // 1. store the num in the ones
  9.         // 2. delete the num in the ones, store the num in the twos
  10.         // 3. delete num in the twos
  11.         
  12.         // a & ~b to ensure the result of a is different from b (b & ~b = 0)
  13.         // & ~b is to ensure not setting b in first loop and not setting a in last loop
  14.         //                                             ones      twos
  15.         // first loop: ones = num, twos = 0            0->1      0->0
  16.         // second loop: ones = 0, twos = num           1->0      0->1
  17.         // third loop: ones = 0, twos = 0              0->0      1->0
  18.         int ones = 0, twos = 0;
  19.         for (int num : nums) {
  20.             ones = (ones ^ num) & ~twos;
  21.             twos = (twos ^ num) & ~ones;
  22.         }
  23.         return ones;
  24.     }
  25.    
  26. //     public int singleNumber(int[] nums) {
  27. //         // time: O(n) 34.62%
  28. //         // space: O(n) 89.64
  29. //         if (nums == null || nums.length == 0) return -1;
  30. //         HashMap<Integer, Integer> map = new HashMap<> ();
  31.         
  32. //         for (int num : nums) {
  33. //             if (map.containsKey(num)) {
  34. //                 map.put(num, map.get(num) + 1);
  35. //             } else {
  36. //                 map.put(num, 1);
  37. //             }
  38. //         }
  39.         
  40. //         for (int key: map.keySet()) {
  41. //             if (map.get(key) == 1){
  42. //                 return key;
  43. //             }
  44. //         }
  45. //         return -1;
  46. //     }
  47. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-3 09:42:03 | 只看该作者
全局:
03/02/2019 Day25

Leetcode 148. Sort List
Importance【4】

解题思路:
主要就是merge sort在linked list上的具体实现。
首先,要将linked list拆分成两个linked list,然后分别对他们sort再merge。
拆分的时候,记得要定义pre,主要用处是把 left和 right 从中间断开。
merge的时候,因为奇偶性,left和right最多相差一个,所以while循环的时候,需要他们都不为null。最后再if判断一下,left 和 right中是否有没有merge上去的元素。

技巧:
利用fast,slow两个node,fast一次两步,slow一次一步,知道fast==null || fast.next==null,最后得到的slow是中间偏左。

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. *     int val;
  5. *     ListNode next;
  6. *     ListNode(int x) { val = x; }
  7. * }
  8. */
  9. class Solution {
  10.     // time: O(nlogn) 5.02%
  11.     // space: O(1) 17.26%
  12.     public ListNode sortList(ListNode head) {
  13.         if (head == null || head.next == null) return head;
  14.         
  15.         ListNode fast = head, slow = head, pre = null;
  16.         // in this way, we get slow as the (n odd) middle point or (n even) middle right
  17.         // fast go forward floor(n/2), slow's index is floor(n/2)
  18.         if (fast != null && fast.next != null) {
  19.             pre = slow;
  20.             slow = slow.next;
  21.             fast = fast.next.next;
  22.         }
  23.         pre.next = null;
  24.         ListNode left = sortList(head);
  25.         ListNode right = sortList(slow);
  26.         
  27.         return merge(left, right);
  28.     }
  29.    
  30.     private ListNode merge(ListNode left, ListNode right) {
  31.         ListNode dummy = new ListNode(0);
  32.         ListNode moving = dummy;
  33.         while (left != null && right != null) {
  34.             if (left.val < right.val) {
  35.                 moving.next = left;
  36.                 left = left.next;
  37.             } else {
  38.                 moving.next = right;
  39.                 right = right.next;
  40.             }
  41.             moving = moving.next;
  42.         }
  43.         if (left != null) moving.next = left;
  44.         if (right != null) moving.next = right;
  45.         return dummy.next;
  46.     }
  47. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-3 23:41:24 | 只看该作者
全局:
03/03/2019 Day26

Leetcode 141. Linked List Cycle
Importance【4】

解题思路:
主要是设置两个指针 fast 和slow对 linked list 进行遍历,fast一次走两步,slow一次走一步。
如果有循环的话,总有一天,fast会和slow重复,指向同一个点。
如果没有循环,fast在遍历完之后跳出循环,始终领先 slow。



  1. /**
  2. * Definition for singly-linked list.
  3. * 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.     // time: O(n) 100%
  14.     // space: O(1) 96.56%
  15.     public boolean hasCycle(ListNode head) {
  16.         if (head == null) return false;
  17.         ListNode slow = head;
  18.         ListNode fast = head;
  19.         while (fast.next != null && fast.next.next != null) {
  20.             slow = slow.next;
  21.             fast = fast.next.next;
  22.             if (fast == slow) return true;
  23.         }
  24.         return false;
  25.         
  26.     }
  27. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-4 00:16:53 | 只看该作者
全局:
03/03/2019 Day26

Leetcode 142. Linked List Cycle II
Importance【4】

解题思路:
主要是设置两个指针 fast 和slow对 linked list 进行遍历,fast一次走两步,slow一次走一步。
如果没有循环,fast会最先遇到null,然后就可以return null了。

如果有循环的话,总有一天,fast会和slow重复,指向同一个点。这个点叫 z。
假设,循环长这样
       n_start -------------- n_cycle_start ---------------- n_meet --|
                                           |                                            |
                                           |--------------------------------------|

  1. /**
  2. * Definition for singly-linked list.
  3. * 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.     public ListNode detectCycle(ListNode head) {
  14.         // time: O(n) 100%
  15.         // space: O(1) 53.27%
  16.         if (head == null) return null;
  17.         ListNode slow = head, fast = head;
  18.         
  19.         while (true) {
  20.             if (fast.next == null || fast.next.next == null) return null;
  21.             slow = slow.next;
  22.             fast = fast.next.next;
  23.             if (slow == fast) break;
  24.         }
  25.         
  26.         slow = head;
  27.         while (slow != fast) {
  28.             slow = slow.next;
  29.             fast = fast.next;
  30.         }
  31.         return slow;
  32.     }
  33. }
复制代码
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-4 00:20:41 | 只看该作者
全局:
03/03/2019 Day26

Leetcode 142. Linked List Cycle II
Importance【4】

解题思路:
主要是设置两个指针 fast 和slow对 linked list 进行遍历,fast一次走两步,slow一次走一步。
如果没有循环,fast会最先遇到null,然后就可以return null了。

如果有循环的话,总有一天,fast会和slow重复,指向同一个点。这个点叫 n_meet。
假设,循环长这样
       n_start -------(a)------- n_cycle_start --------(b)-------- n_meet --|
                                           |                                                     |
                                           |-------------------------(c)-----------------|

可以知道 slow 走过的距离 a+b,fast走过的距离 a +b + c + b。
所以,2 * (a + b) = a + b + c + b  -->  a = c
所以,我们只要把slow重新写设置成head,fast放在原来相遇的地方,然后让他们一次都走一步,一起走a/c步,这次相遇的地方就是cycle start
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-4 00:21:18 | 只看该作者
全局:

03/03/2019 Day26

Leetcode 142. Linked List Cycle II
Importance【4】

解题思路:
主要是设置两个指针 fast 和slow对 linked list 进行遍历,fast一次走两步,slow一次走一步。
如果没有循环,fast会最先遇到null,然后就可以return null了。

如果有循环的话,总有一天,fast会和slow重复,指向同一个点。这个点叫 n_meet。
假设,循环长这样
       n_start -------(a)------- n_cycle_start --------(b)-------- n_meet --|
                                           |                                                     |
                                           |-------------------------(c)-----------------|

可以知道 slow 走过的距离 a+b,fast走过的距离 a +b + c + b。
所以,2 * (a + b) = a + b + c + b  -->  a = c
所以,我们只要把slow重新写设置成head,fast放在原来相遇的地方,然后让他们一次都走一步,一起走a/c步,这次相遇的地方就是cycle start

  1. /**
  2. * Definition for singly-linked list.
  3. * 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.     public ListNode detectCycle(ListNode head) {
  14.         // time: O(n) 100%
  15.         // space: O(1) 53.27%
  16.         if (head == null) return null;
  17.         ListNode slow = head, fast = head;
  18.         
  19.         while (true) {
  20.             if (fast.next == null || fast.next.next == null) return null;
  21.             slow = slow.next;
  22.             fast = fast.next.next;
  23.             if (slow == fast) break;
  24.         }
  25.         
  26.         slow = head;
  27.         while (slow != fast) {
  28.             slow = slow.next;
  29.             fast = fast.next;
  30.         }
  31.         return slow;
  32.     }
  33. }
复制代码

补充内容 (2019-3-4 00:21):
附一个写的比较好的讲解:https://www.cnblogs.com/hiddenfox/p/3408931.html
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-5 01:26:44 | 只看该作者
全局:
03/03/2019 Day26

Leetcode 152. Maximum Product Subarray
Importance【4】

解题思路:
解题的关键还在是设置变量上。
首先,因为有负数的存在,所以最大最小值随时可能相互转化,所以就要设置 curMax, curMin 两个变量记录最大最小值,并在每次遇到新的数之后更新curMax,curMin。
其次,因为array可能有0, 在遇到0之后,curMax,curMin都会变成 0。所以说还要再增加一个max(max(..., ....), num[i]) 来引入num[ i ] 来重新restart

  1. class Solution {
  2.     public int maxProduct(int[] nums) {
  3.         // time: O(n) 99.25%
  4.         // space: O(1) 79.57%
  5.         if (nums == null || nums.length == 0) return 0;
  6.         int curMax = nums[0];
  7.         int curMin = nums[0];
  8.         int res = nums[0];
  9.         for (int i = 1; i < nums.length; i++) {
  10.             int temp = curMax;
  11.             // add A[i] in the last, since after encountering 0, curMax = curMin = 0, we need this nums[i] to restart
  12.             curMax = Math.max(Math.max(curMax * nums[i], curMin * nums[i]), nums[i]);
  13.             curMin = Math.min(Math.min(temp * nums[i], curMin * nums[i]), nums[i]);
  14.         
  15.             res = Math.max(res, curMax);
  16.         }
  17.         return res;
  18.     }
  19. }
复制代码

补充内容 (2019-3-5 01:27):
日期更正:03/04/2019 Day27
回复

使用道具 举报

🔗
 楼主| AChris 2019-3-6 00:13:25 | 只看该作者
全局:

03/05/2019 Day28

Leetcode 206. Reverse Linked List
Importance【4】

解题思路:暴力解决
1.递归法:每次对nextNode进行reverse并返回newHead
2.遍历法:front用于链表的 next 一点一点往前走,mid 和 latter 用来设置新的结构关系




  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. *     int val;
  5. *     ListNode next;
  6. *     ListNode(int x) { val = x; }
  7. * }
  8. */
  9. class Solution {
  10.     // method1: recursive
  11.     public ListNode reverseList(ListNode head) {
  12.         // time: O(n) 100%
  13.         // space: O(n) 8.72%
  14.         if (head == null || head.next == null) return head;
  15.         ListNode nextNode = head.next;
  16.         ListNode newHead = reverseList(nextNode);
  17.         nextNode.next = head;
  18.         head.next = null;
  19.         return newHead;
  20.     }
  21.    
  22. //     // method2: iterative
  23. //     public ListNode reverseList(ListNode head) {
  24. //         // time: O(n) 100%
  25. //         // space: O(1) 11.36%
  26. //         if (head == null || head.next == null) return head;
  27. //         ListNode front = head.next;
  28. //         ListNode mid = head;
  29. //         ListNode latter = null;
  30.         
  31. //         while(front != null) {
  32. //             mid.next = latter;

  33. //             latter = mid;
  34. //             mid = front;
  35. //             front = front.next;
  36. //         }
  37. //         mid.next = latter;
  38. //         return mid;
  39. //     }
  40. }
复制代码
回复

使用道具 举报

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

本版积分规则

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