diff --git a/003._longest_substring_without_repeating_characters.md b/003._longest_substring_without_repeating_characters.md index 08ede7eaaffcd6eb28c4a1cf1129c5ac1847d065..188a6c26dafcca58cd27a2212a9205e39ad7ef4d 100644 --- a/003._longest_substring_without_repeating_characters.md +++ b/003._longest_substring_without_repeating_characters.md @@ -1,4 +1,4 @@ -###3. Longest Substring Without Repeating Characters +### 3. Longest Substring Without Repeating Characters 题目: diff --git a/141._linked_list_cycle.md b/141._linked_list_cycle.md index e671e494246793b1df2a5f3fcd023a72714d8adb..2cf604e4e52a0f8704a60f8f790bb7a502cd54ba 100644 --- a/141._linked_list_cycle.md +++ b/141._linked_list_cycle.md @@ -1,81 +1,105 @@ -###141. Linked List Cycle - -题目: - - - - -难度: - -Easy - - -想法一: - -直接超时 - +### 141. Linked List Cycle + +题目: + + + + +难度: + +Easy + + +想法一: + +直接超时 + ``` -class Solution(object): - def hasCycle(self, head): - """ - :type head: ListNode - :rtype: bool - """ - if head == None: return False - lst = [] - cur = head - while cur: - if cur in lst: - return True - lst.append(cur) - cur = cur.next - return False -``` - - - -想法二:相当用boolean array记录某个点是否被访问过,时间,空间复杂度都是O(n) - -``` -class Solution(object): - def hasCycle(self, head): - """ - :type head: ListNode - :rtype: bool - """ - if head == None: return False - dictx = {} - cur = head - while cur: - if cur in dictx: - return True - dictx[cur] = 1 - cur = cur.next - return False -``` - -结果这种方法的run time还比较快 - -查了一下,有解答说可以有空间复杂度O(1),时间复杂度O(n)。两个指针,一个快一个慢,快的每次走两步,慢的每次走一步,如果有环,最终会在某处相遇。这也是一个算法。这种快慢指针配合已经不是第一次遇到了,比如找linklist中间的node。 - - - -但是并没有觉得这样的算法是O(n), worst case time complexity is O(N+K), which is O(n). - - -``` -class Solution(object): - def hasCycle(self, head): - """ - :type head: ListNode - :rtype: bool - """ - slow = head - fast = head - while slow and fast and fast.next: - slow = slow.next - fast = fast.next.next - if slow == fast: - return True - return False -``` +class Solution(object): + def hasCycle(self, head): + """ + :type head: ListNode + :rtype: bool + """ + if head == None: return False + lst = [] + cur = head + while cur: + if cur in lst: + return True + lst.append(cur) + cur = cur.next + return False +``` + + + +想法二:相当用boolean array记录某个点是否被访问过,时间,空间复杂度都是O(n) + +``` +class Solution(object): + def hasCycle(self, head): + """ + :type head: ListNode + :rtype: bool + """ + if head == None: return False + dictx = {} + cur = head + while cur: + if cur in dictx: + return True + dictx[cur] = 1 + cur = cur.next + return False +``` + +结果这种方法的run time还比较快 + +查了一下,有解答说可以有空间复杂度O(1),时间复杂度O(n)。两个指针,一个快一个慢,快的每次走两步,慢的每次走一步,如果有环,最终会在某处相遇。这也是一个算法。这种快慢指针配合已经不是第一次遇到了,比如找linklist中间的node。 + + + +但是并没有觉得这样的算法是O(n), worst case time complexity is O(N+K), which is O(n). + + +```python +python +class Solution(object): + def hasCycle(self, head): + """ + :type head: ListNode + :rtype: bool + """ + slow = head + fast = head + while slow and fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + return True + return False +``` + + +```java +java +public class Solution { + public boolean hasCycle(ListNode head) { + if (head == null){ + return false; + } + ListNode fast = head; + ListNode slow = head; + while (fast != null && slow != null && fast.next != null){ + fast = fast.next.next; + slow = slow.next; + if (slow == fast){ + return true; + } + } + return false; + } +} +``` + diff --git a/587.-Erect-the-Fence .md b/587.-Erect-the-Fence .md new file mode 100644 index 0000000000000000000000000000000000000000..396e5e18caad26258c7785d1625fcaac165b4b32 --- /dev/null +++ b/587.-Erect-the-Fence .md @@ -0,0 +1,101 @@ +### 587. Erect the Fence + + +题目: + + + +难度: + +Hard + + + +思路 + +题目要求用一个围栏把所有的点(🌲)围起来,然后求处于围栏上点(🌲)的集合。 + +我们可以发现,从最左边的那个点一直往右走,只要一直都是走的逆时针方向,那么我们一定可以找到这条围栏。那么接下来就考虑最简单的情况, + +- 只有两个点```p```和```q```,我们从```p```走到```q```,当```p```到原点这条直线的斜率小于```q```到原点这条直线的斜率时,```p->q```就是沿逆时针方向走的; +- 接下来考虑3个点:```p,q,r```,以```p```为参照点(即前面的原点),那么从```q```走到```r```的时候,只要```q```到```q```这条直线的斜率小于```r```到```p```这条直线的斜率,```q->r```就是沿逆时针方向走的。 + +因此,我们只要构建一个```orientation```函数,就可以判断出目前我们的围栏是不是沿着逆时针在走下去了。 + +我们用一个```stack```来存放目前认为在围栏上的点的集合,然后把所有的点按照指定规则排好序:```先按照点的x坐标升序排列,如果x相等则按照点的y坐标升序排列```。这样我们依次取点,只要stack里面的点大于等于2个我们就要无限进行判断是否走的是逆时针,如果不是就把stack里面最后那个点pop出去(可能一直pop到只剩一个点),否则就把目前的这个点加入到stack中去,因为目前它还是在逆时针方向上的。 + +从左往右走完一遍points之后,我们围栏的下部分lower hull就构建好了,此时我们还要构建围栏的upper hull,因此我们将points逆序一下,从右往左再来一次遍历,仍然看是否走的是逆时针。但是这次遍历我们需要进行一个判断,就是之前放进stack的点,此时我们还是会经过它,如果它已经在stack里面了,我们就不需要再加进去了,同时这样也避免了我们把最左边的点重复加进去。 + + + +```python +python +import functools +class Solution: + def outerTrees(self, points): + """ + :type points: List[Point] + :rtype: List[Point] + """ + def orientation(p, q, r): + return (q.y - p.y)*(r.x - p.x) - (r.y - p.y)*(q.x - p.x) + def myComparator(p,q): + return p.x - q.x if p.x != q.x else p.y - q.y + + stack= [] + points.sort(key = functools.cmp_to_key(myComparator)) + for i in range(len(points)): + while (len(stack) >= 2 and orientation(stack[-2],stack[-1],points[i]) > 0): + stack.pop() + stack.append(points[i]) + points.reverse(); + for i in range(len(points)): + while (len(stack) >= 2 and orientation(stack[-2],stack[-1],points[i]) > 0): + stack.pop() + if points[i] not in stack: + stack.append(points[i]) + return stack +``` + +```java +java +class Solution { + public List outerTrees(Point[] points) { + List res = new ArrayList(); + Arrays.sort(points, new Comparator(){ + @Override + public int compare(Point p, Point q){ + return p.x == q.x ? p.y - q.y : p.x - q.x; + } + }); + Stack stack = new Stack<>(); + for (int i = 0; i < points.length; i++){ + while(stack.size() >= 2 && orientation(stack.get(stack.size() - 2), stack.peek(), points[i]) > 0){ + stack.pop(); + } + stack.push(points[i]); + } + //stack.pop(); + for (int i = points.length - 1; i >= 0; i--){ + while(stack.size() >= 2 && orientation(stack.get(stack.size() - 2), stack.peek(), points[i]) > 0){ + stack.pop(); + } + stack.push(points[i]); + } + res.addAll(new HashSet<>(stack)); + return res; + } + + public int orientation(Point p, Point q, Point r){ + return (q.y - p.y)*(r.x - p.x) - (r.y - p.y)*(q.x - p.x); + } +} +``` + + + +Author: Keqi Huang + +If you like it, please spread your support + +![Support](https://github.com/Lisanaaa/myTODOs/blob/master/WechatIMG17.jpeg) \ No newline at end of file