From 505d1f0b25b9f26d19304f244160df8f74dfc3d2 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 10:19:12 +0800 Subject: [PATCH 01/69] =?UTF-8?q?Update=200023-=E5=90=88=E5=B9=B6K?= =?UTF-8?q?=E4=B8=AA=E6=8E=92=E5=BA=8F=E9=93=BE=E8=A1=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...22\345\272\217\351\223\276\350\241\250.py" | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git "a/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" "b/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" index 8581c27..dd6a0a5 100644 --- "a/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" +++ "b/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" @@ -4,27 +4,58 @@ # self.val = x # self.next = None -class Solution(object): - def mergeKLists(self, lists): - """ - :type lists: List[ListNode] - :rtype: ListNode - """ - from heapq import * - pq = [] - for i in range(len(lists)): - if lists[i]: - heappush(pq, (lists[i].val, i)) - lists[i] = lists[i].next +# 优先级队列 +# 时间复杂度:O(n*log(k))O(n∗log(k)) +# class Solution(object): +# def mergeKLists(self, lists): +# """ +# :type lists: List[ListNode] +# :rtype: ListNode +# """ +# from heapq import * +# pq = [] +# for i in range(len(lists)): +# if lists[i]: +# heappush(pq, (lists[i].val, i)) +# lists[i] = lists[i].next + +# dummy = ListNode(1) +# p = dummy +# while pq: +# val, idx = heappop(pq) +# p.next = ListNode(val) +# p = p.next +# if lists[idx]: +# heappush(pq, (lists[idx].val, idx)) +# lists[idx] = lists[idx].next +# return dummy.next + +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +# 分而治之,两两合并 +class Solution: + def mergeKLists(self, lists: List[ListNode]) -> ListNode: + if not lists:return + n = len(lists) + return self.merge(lists, 0, n-1) + def merge(self,lists, left, right): + if left == right: + return lists[left] + mid = left + (right - left) // 2 + l1 = self.merge(lists, left, mid) + l2 = self.merge(lists, mid+1, right) + return self.mergeTwoLists(l1, l2) + def mergeTwoLists(self,l1, l2): + if not l1:return l2 + if not l2:return l1 + if l1.val < l2.val: + l1.next = self.mergeTwoLists(l1.next, l2) + return l1 + else: + l2.next = self.mergeTwoLists(l1, l2.next) + return l2 - dummy = ListNode(1) - p = dummy - while pq: - val, idx = heappop(pq) - p.next = ListNode(val) - p = p.next - if lists[idx]: - heappush(pq, (lists[idx].val, idx)) - lists[idx] = lists[idx].next - return dummy.next - \ No newline at end of file From 65b117d3e4923a50f66450ffa9ec428427b88535 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 10:49:54 +0800 Subject: [PATCH 02/69] =?UTF-8?q?Update=200031-=E4=B8=8B=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8E=92=E5=88=97.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\344\270\252\346\216\222\345\210\227.py" | 74 ++++++++++++------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git "a/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" "b/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" index 5538d3c..0d6deaf 100644 --- "a/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" +++ "b/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" @@ -1,30 +1,52 @@ -class Solution(object): - def nextPermutation(self, nums): - """ - :type nums: List[int] - :rtype: None Do not return anything, modify nums in-place instead. - """ - if not nums or len(nums) == 1: - return nums - # print nums, sorted(nums)[::-1] - if nums == sorted(nums)[::-1]: - nums[:] = nums[::-1] - return +# class Solution(object): +# def nextPermutation(self, nums): +# """ +# :type nums: List[int] +# :rtype: None Do not return anything, modify nums in-place instead. +# """ +# if not nums or len(nums) == 1: +# return nums +# # print nums, sorted(nums)[::-1] +# if nums == sorted(nums)[::-1]: +# nums[:] = nums[::-1] +# return - i = len(nums) - 1 - while(i - 1 >= 0 and nums[i - 1] >= nums[i]): - i -= 1 - i -= 1 - tmp = nums[i] +# i = len(nums) - 1 +# while(i - 1 >= 0 and nums[i - 1] >= nums[i]): +# i -= 1 +# i -= 1 +# tmp = nums[i] +# j = len(nums) - 1 +# while(j >= i and nums[j] <= tmp): +# j -= 1 +# if nums[j] > tmp: +# break + +# # print tmp, nums[j], nums[i] +# nums[i], nums[j] = nums[j], nums[i] +# # print nums +# nums[i+ 1:] = nums[i + 1:][::-1] +# return + +class Solution: +def nextPermutation(self, nums: List[int]) -> None: + i = len(nums) - 2 + while i >= 0 and nums[i] >= nums[i + 1]: + i -= 1 + if i >= 0: j = len(nums) - 1 - while(j >= i and nums[j] <= tmp): + while j >= 0 and nums[i] >= nums[j]: j -= 1 - if nums[j] > tmp: - break - - # print tmp, nums[j], nums[i] nums[i], nums[j] = nums[j], nums[i] - # print nums - nums[i+ 1:] = nums[i + 1:][::-1] - return - \ No newline at end of file + + left, right = i + 1, len(nums) - 1 + while left < right: + nums[left], nums[right] = nums[right], nums[left] + left += 1 + right -= 1 + +# 作者:LeetCode-Solution +# 链接:https://leetcode-cn.com/problems/next-permutation/solution/xia-yi-ge-pai-lie-by-leetcode-solution/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + From d68f83471afaed9b2535ea021cf6ebb864a0548d Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 10:50:52 +0800 Subject: [PATCH 03/69] =?UTF-8?q?Update=200032-=E6=9C=80=E9=95=BF=E6=9C=89?= =?UTF-8?q?=E6=95=88=E6=8B=AC=E5=8F=B7.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" "b/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" index 38e69fd..cd5509a 100644 --- "a/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" +++ "b/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" @@ -15,5 +15,6 @@ def longestValidParentheses(self, s): res = max(res, i - stack[-1]) else: stack.append(i) +# print(stack) - return res \ No newline at end of file + return res From d03a44813603c10228fd6477c4502645a68dd269 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 10:53:08 +0800 Subject: [PATCH 04/69] =?UTF-8?q?Update=200032-=E6=9C=80=E9=95=BF=E6=9C=89?= =?UTF-8?q?=E6=95=88=E6=8B=AC=E5=8F=B7.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...11\346\225\210\346\213\254\345\217\267.py" | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git "a/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" "b/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" index cd5509a..bf32e48 100644 --- "a/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" +++ "b/0032.\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267/0032-\346\234\200\351\225\277\346\234\211\346\225\210\346\213\254\345\217\267.py" @@ -1,3 +1,28 @@ +# 思路 +# 栈的功能:栈存储索引。在遍历过程中,只要有两个连续索引对应字符可以构成一对括号就出栈,这样栈中存储的都是到当前位置暂时不可以构成括号的索引。 + +# 那满足什么条件才会导致当前不可以构成括号呢? +# i. 当前栈为空。当前字符s[i]将会是栈中第一个字符,无法跟之前的字符构成一对括号 +# ii. 当前字符s[i]是左括号'('。左括号无法跟栈顶元素构成一对括号 +# iii. 栈顶元素是右括号')'。无论当前字符s[i]是什么,都无法和栈顶元素构成一对括号 + +# 其实也就是栈顶元素必须为'(',当前字符s[i]必须为')',这样才能构成一对括号 + +# 构成一对括号以后,栈顶元素出栈。 +# 这样就可以满足前面说的栈中存储的都是当前暂时不可以构成括号的索引 + +# 当前有效括号的长度 = 当前索引i - 栈顶存储的索引stack[-1] +# 最后要返回的最长有效括号长度即为res = max(res, i - stack[-1]) +# 因为此时栈可能为空,如果为空就是res = max(res, i - (-1)) + +# 时间复杂度:O(n)O(n) +# 空间复杂度:O(n)O(n) + +# 作者:edelweisskoko +# 链接:https://leetcode-cn.com/problems/longest-valid-parentheses/solution/32-zui-chang-you-xiao-gua-hao-fu-zhu-zha-1cqq/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + class Solution(object): def longestValidParentheses(self, s): """ From 1a7b940fd605459b629736459f64b181151233f6 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 10:59:38 +0800 Subject: [PATCH 05/69] =?UTF-8?q?Update=200033-=E6=90=9C=E7=B4=A2=E6=97=8B?= =?UTF-8?q?=E8=BD=AC=E6=8E=92=E5=BA=8F=E6=95=B0=E7=BB=84.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...22\345\272\217\346\225\260\347\273\204.py" | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git "a/0033.\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204/0033-\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.py" "b/0033.\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204/0033-\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.py" index e6c5746..ee8faa6 100644 --- "a/0033.\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204/0033-\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.py" +++ "b/0033.\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204/0033-\346\220\234\347\264\242\346\227\213\350\275\254\346\216\222\345\272\217\346\225\260\347\273\204.py" @@ -1,42 +1,42 @@ -class Solution(object): - def search(self, nums, target): - """ - :type nums: List[int] - :type target: int - :rtype: int - """ - #1. ת - #2. ȷtargetһȻ +# 思路和算法 + +# 对于有序数组,可以使用二分查找的方法查找元素。 + +# 但是这道题中,数组本身不是有序的,进行旋转后只保证了数组的局部是有序的,这还能进行二分查找吗?答案是可以的。 + +# 可以发现的是,我们将数组从中间分开成左右两部分的时候,一定有一部分的数组是有序的。拿示例来看,我们从 6 这个位置分开以后数组变成了 [4, 5, 6] 和 [7, 0, 1, 2] 两个部分,其中左边 [4, 5, 6] 这个部分的数组是有序的,其他也是如此。 + +# 这启示我们可以在常规二分查找的时候查看当前 mid 为分割位置分割出来的两个部分 [l, mid] 和 [mid + 1, r] 哪个部分是有序的,并根据有序的那个部分确定我们该如何改变二分查找的上下界,因为我们能够根据有序的那部分判断出 target 在不在这个部分: + +# 如果 [l, mid - 1] 是有序数组,且 target 的大小满足 [\textit{nums}[l],\textit{nums}[mid])[nums[l],nums[mid]),则我们应该将搜索范围缩小至 [l, mid - 1],否则在 [mid + 1, r] 中寻找。 +# 如果 [mid, r] 是有序数组,且 target 的大小满足 (\textit{nums}[mid+1],\textit{nums}[r]](nums[mid+1],nums[r]],则我们应该将搜索范围缩小至 [mid + 1, r],否则在 [l, mid - 1] 中寻找。 + +# 时间复杂度: O(\log n),其中 nn 为 \textit{nums}nums 数组的大小。整个算法时间复杂度即为二分查找的时间复杂度 O(\log n)O(logn)。 + +# 空间复杂度: O(1) 。我们只需要常数级别的空间存放变量。 + +class Solution: + def search(self, nums: List[int], target: int) -> int: if not nums: return -1 - if len(nums) == 1: - return 0 if nums[0] == target else -1 - midposition = -1 - left, right = 0, len(nums) - 1 - while left <= right: - mid = (left + right) // 2 - # print mid - if mid + 1 < len(nums) and nums[mid] > nums[mid + 1]: - midposition = mid - break - elif nums[mid] >= nums[0]: - left = mid + 1 - elif nums[mid] <= nums[-1]: - right = mid - 1 - # print midposition - if midposition != -1: - if target >= nums[0]: - left, right = 0, midposition - else: - left, right = midposition + 1, len(nums) - 1 - else: - left, right = 0, len(nums) - 1 - while(left <= right): - mid = (left + right) // 2 + l, r = 0, len(nums) - 1 + while l <= r: + mid = (l + r) // 2 if nums[mid] == target: return mid - elif nums[mid] > target: - right = mid - 1 + if nums[0] <= nums[mid]: + if nums[0] <= target < nums[mid]: + r = mid - 1 + else: + l = mid + 1 else: - left = mid + 1 - return -1 \ No newline at end of file + if nums[mid] < target <= nums[len(nums) - 1]: + l = mid + 1 + else: + r = mid - 1 + return -1 + +# 作者:LeetCode-Solution +# 链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array/solution/sou-suo-xuan-zhuan-pai-xu-shu-zu-by-leetcode-solut/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 3f781d96a9bc224fcf37525ab36a59fbfc7adb6f Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 11:08:14 +0800 Subject: [PATCH 06/69] =?UTF-8?q?Update=200034-=E5=9C=A8=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E4=B8=AD=E6=9F=A5=E6=89=BE=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E7=9A=84=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=92=8C=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=BD=8D=E7=BD=AE.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\344\270\252\344\275\215\347\275\256.py" | 109 +++++++++--------- 1 file changed, 57 insertions(+), 52 deletions(-) diff --git "a/0034.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/0034-\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.py" "b/0034.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/0034-\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.py" index 6916af6..9c7f1fb 100644 --- "a/0034.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/0034-\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.py" +++ "b/0034.\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256/0034-\345\234\250\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\346\237\245\346\211\276\345\205\203\347\264\240\347\232\204\347\254\254\344\270\200\344\270\252\345\222\214\346\234\200\345\220\216\344\270\200\344\270\252\344\275\215\347\275\256.py" @@ -1,56 +1,61 @@ -class Solution(object): - def searchRange(self, nums, target): - """ - :type nums: List[int] - :type target: int - :rtype: List[int] - """ - lo, hi = 0, len(nums) - 1 - - while lo <= hi: - - mid = (lo + hi) // 2 - # print lo, hi, mid, nums - if nums[mid] == target: - break - elif nums[mid] < target: - lo = mid + 1 - else: - hi = mid - 1 - - if lo > hi: - return [-1, -1] - midposition = mid - leftside, rightside = midposition, midposition - #߽ - # print 1 - lo, hi = 0, midposition - while lo <= hi: - # print lo, hi, mid - mid = (lo + hi) // 2 - if nums[mid] < target: - lo = mid + 1 - elif nums[mid] == target: - if mid == 0 or (mid - 1 >= 0 and nums[mid - 1] < target): - leftside = mid +# 直观解法 +class Solution1(object): + def searchRange(self, nums: List[int], target: int) -> List[int]: + if target not in nums: + return [-1, -1] + ans = [] + for i in range(len(nums)): + if nums[i] == target: + ans.append(i) break - else: - hi = mid - 1 - # print 1 - #ұ߽ - lo, hi = midposition, len(nums) - 1 - while lo <= hi: - mid = (lo + hi) // 2 - if nums[mid] > target: - hi = mid - 1 - elif nums[mid] == target: - if mid == len(nums) - 1 or (mid + 1 < len(nums) and nums[mid + 1] > target): - rightside = mid + + for i in range(len(nums)-1, -1, -1): + if nums[i] == target: + ans.append(i) break - else: - lo = mid + 1 - - return [leftside, rightside] + return ans + +# 二分查找 +# 思路: +# 二分查找算法就一种思想:减而治之(逐渐缩小问题规模),也可以视为「排除法」(一直排除一定不是目标元素的区间,思想依然是逐渐缩小搜索区间); +# 根据看到的中间位置的元素的值 nums[mid] 可以把待搜索区间分为两个部分:「一定不存在目标元素的区间」和「可能存在目标元素的区间」。因此 mid 只可能被分到这两个区间的其中一个,即:while 里面的 if 和 else 就两种写法: +# 如果 mid 分到左边区间,即区间分成 [left..mid] 与 [mid + 1..right],此时分别设置 right = mid 与 left = mid + 1; +# 如果 mid 分到右边区间,即区间分成 [left..mid - 1] 与 [mid..right],此时分别设置 right = mid - 1 与 left = mid。 +# 分类讨论的时候,不断排除不是目标元素的区间,以确定下一轮搜索的区间。即一直思考下一轮搜索区间是什么,以 左闭右闭区间 的形式表现出来,这样到底变化 left 还是变化 right,加不加 11 就会很清楚; +# 在退出循环的时候。如果区间一定存在目标元素,直接返回 left 或者 right。否则还需要单独做一次判断; +# 在循环体里,对 nums[mid] 与 target 的大小关系的判断需要分类讨论。 +# 这里需要仔细一点,向左走还是向右走结果错了的话会导致整个结果都错。如果写成三个分支去判断; +# 最后要合并成两个分支。这样退出循环的时候,left 和 right 才会合并到一起。我们才可以不用纠结到底返回 left 还是返回 right。 + +# 作者:liweiwei1419 +# 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/si-lu-hen-jian-dan-xi-jie-fei-mo-gui-de-er-fen-cha/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 +class Solution(object): + def searchRange(self, nums: List[int], target: int) -> List[int]: + if len(nums)==0: + return [-1,-1] + left=0 + right=len(nums)-1 + while lefttarget: + r2=m2-1 + return [left,l2-1] - \ No newline at end of file + From 10ab7671a15b879f2f43ea1db6db502a928d35b1 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 15:08:55 +0800 Subject: [PATCH 07/69] =?UTF-8?q?Update=200042-=E6=8E=A5=E9=9B=A8=E6=B0=B4?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-\346\216\245\351\233\250\346\260\264.py" | 64 ++++++++++++------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git "a/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" "b/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" index 2d3dc43..8991e30 100644 --- "a/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" +++ "b/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" @@ -1,24 +1,42 @@ -class Solution(object): - def trap(self, height): - """ - :type height: List[int] - :rtype: int - """ - height = [0] + height + [0] - left_max = [0 for _ in height] - right_max = [0 for _ in height] +# 动态规划 +# 对于下标 ii,下雨后水能到达的最大高度等于下标 ii 两边的最大高度的最小值,下标 ii 处能接的雨水量等于下标 ii 处的水能到达的最大高度减去 \textit{height}[i]height[i]。 + +# 朴素的做法是对于数组 \textit{height}height 中的每个元素,分别向左和向右扫描并记录左边和右边的最大高度,然后计算每个下标位置能接的雨水量。假设数组 \textit{height}height 的长度为 nn,该做法需要对每个下标位置使用 O(n)O(n) 的时间向两边扫描并得到最大高度,因此总时间复杂度是 O(n^2)O(n +# 2 +# )。 + +# 上述做法的时间复杂度较高是因为需要对每个下标位置都向两边扫描。如果已经知道每个位置两边的最大高度,则可以在 O(n)O(n) 的时间内得到能接的雨水总量。使用动态规划的方法,可以在 O(n)O(n) 的时间内预处理得到每个位置两边的最大高度。 + +# 创建两个长度为 nn 的数组 \textit{leftMax}leftMax 和 \textit{rightMax}rightMax。对于 0 \le i int: + if not height: + return 0 - - for i in range(1, len(height)): - left_max[i] = max(height[i], left_max[i - 1]) - - for i in range(len(height) - 2, -1, -1): - # print i - right_max[i] = max(height[i], right_max[i + 1]) - # print left_max, right_max - # res = [0 for _ in height] - res = 0 - for i in range(1, len(height) - 2): - res += min(left_max[i], right_max[i]) - height[i] - - return res \ No newline at end of file + n = len(height) + leftMax = [height[0]] + [0] * (n - 1) + for i in range(1, n): + leftMax[i] = max(leftMax[i - 1], height[i]) + + rightMax = [0] * (n - 1) + [height[n - 1]] + for i in range(n - 2, -1, -1): + rightMax[i] = max(rightMax[i + 1], height[i]) + + ans = sum(min(leftMax[i], rightMax[i]) - height[i] for i in range(n)) + return ans + +# 作者:LeetCode-Solution +# 链接:https://leetcode-cn.com/problems/trapping-rain-water/solution/jie-yu-shui-by-leetcode-solution-tuvc/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From de67ee6c8db7592a6947197c32aac71bdd3b18f1 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:16:12 +0800 Subject: [PATCH 08/69] =?UTF-8?q?Update=200053-=E6=9C=80=E5=A4=A7=E5=AD=90?= =?UTF-8?q?=E5=BA=8F=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\200\345\244\247\345\255\220\345\272\217\345\222\214.py" | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git "a/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214/0053-\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" "b/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214/0053-\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" index 4358bfe..66ecd65 100644 --- "a/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214/0053-\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" +++ "b/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214/0053-\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214.py" @@ -1,3 +1,7 @@ +# 动态规划转移方程: +# f(i)=max{f(i−1)+nums[i],nums[i]} + + class Solution(object): def maxSubArray(self, nums): """ @@ -16,4 +20,4 @@ def maxSubArray(self, nums): else: dp[i] = x - return max(dp) \ No newline at end of file + return max(dp) From 75cc6e3904249123653bc706a7782a1b44f78153 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:17:26 +0800 Subject: [PATCH 09/69] =?UTF-8?q?Update=200055-=E8=B7=B3=E8=B7=83=E6=B8=B8?= =?UTF-8?q?=E6=88=8F.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5-\350\267\263\350\267\203\346\270\270\346\210\217.py" | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git "a/0055.\350\267\263\350\267\203\346\270\270\346\210\217/0055-\350\267\263\350\267\203\346\270\270\346\210\217.py" "b/0055.\350\267\263\350\267\203\346\270\270\346\210\217/0055-\350\267\263\350\267\203\346\270\270\346\210\217.py" index b6283c9..097f4d2 100644 --- "a/0055.\350\267\263\350\267\203\346\270\270\346\210\217/0055-\350\267\263\350\267\203\346\270\270\346\210\217.py" +++ "b/0055.\350\267\263\350\267\203\346\270\270\346\210\217/0055-\350\267\263\350\267\203\346\270\270\346\210\217.py" @@ -1,3 +1,9 @@ +# 解题思路: +# 如果某一个作为 起跳点 的格子可以跳跃的距离是 3,那么表示后面 3 个格子都可以作为 起跳点。 +# 可以对每一个能作为 起跳点 的格子都尝试跳一次,把 能跳到最远的距离 不断更新。 +# 如果可以一直跳到最后,就成功了。 + + class Solution(object): def canJump(self, nums): """ @@ -9,4 +15,4 @@ def canJump(self, nums): while start <= end and end < len(nums): end = max(end, start + nums[start]) start += 1 - return end >= len(nums) - 1 \ No newline at end of file + return end >= len(nums) - 1 From e02c08fddafbd3b9115d0e32ddb57e063537d935 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:24:03 +0800 Subject: [PATCH 10/69] =?UTF-8?q?Update=200056-=E5=90=88=E5=B9=B6=E5=8C=BA?= =?UTF-8?q?=E9=97=B4.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...10\345\271\266\345\214\272\351\227\264.py" | 75 ++++++++++++++----- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git "a/0056.\345\220\210\345\271\266\345\214\272\351\227\264/0056-\345\220\210\345\271\266\345\214\272\351\227\264.py" "b/0056.\345\220\210\345\271\266\345\214\272\351\227\264/0056-\345\220\210\345\271\266\345\214\272\351\227\264.py" index c005fbe..db979e5 100644 --- "a/0056.\345\220\210\345\271\266\345\214\272\351\227\264/0056-\345\220\210\345\271\266\345\214\272\351\227\264.py" +++ "b/0056.\345\220\210\345\271\266\345\214\272\351\227\264/0056-\345\220\210\345\271\266\345\214\272\351\227\264.py" @@ -1,24 +1,59 @@ -class Solution(object): - def merge(self, intervals): - """ - :type intervals: List[List[int]] - :rtype: List[List[int]] - """ - if not intervals or not intervals[0]: - return intervals - - intervals = sorted(intervals, key = lambda x:x[0]) +# 思路 +# 如果我们按照区间的左端点排序,那么在排完序的列表中,可以合并的区间一定是连续的。 + +# 算法 +# 我们用数组 merged 存储最终的答案。 +# 首先,我们将列表中的区间按照左端点升序排序。然后我们将第一个区间加入 merged 数组中,并按顺序依次考虑之后的每个区间: +# 如果当前区间的左端点在数组 merged 中最后一个区间的右端点之后,那么它们不会重合,我们可以直接将这个区间加入数组 merged 的末尾; +# 否则,它们重合,我们需要用当前区间的右端点更新数组 merged 中最后一个区间的右端点,将其置为二者的较大值。 + +# 复杂度分析 +# 时间复杂度:O(nlogn),其中 nn 为区间的数量。除去排序的开销,我们只需要一次线性扫描,所以主要的时间开销是排序的 O(nlogn)。 +# 空间复杂度:O(logn),其中 nn 为区间的数量。这里计算的是存储答案之外,使用的额外空间。O(logn) 即为排序所需要的空间复杂度。 - res = [] - start, end = intervals[0][0], intervals[0][1] + +class Solution: + def merge(self, intervals: List[List[int]]) -> List[List[int]]: + intervals.sort(key=lambda x: x[0]) + + merged = [] for interval in intervals: - s, e = interval[0], interval[1] - - if s <= end: # overlap - end = max(end, e) + # 如果列表为空,或者当前区间与上一区间不重合,直接添加 + if not merged or merged[-1][1] < interval[0]: + merged.append(interval) else: - res.append([start, end]) - start, end = s, e + # 否则的话,我们就可以与上一区间进行合并 + merged[-1][1] = max(merged[-1][1], interval[1]) + + return merged + +# 作者:LeetCode-Solution +# 链接:https://leetcode-cn.com/problems/merge-intervals/solution/he-bing-qu-jian-by-leetcode-solution/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + +# 原始解法 +# class Solution(object): +# def merge(self, intervals): +# """ +# :type intervals: List[List[int]] +# :rtype: List[List[int]] +# """ +# if not intervals or not intervals[0]: +# return intervals + +# intervals = sorted(intervals, key = lambda x:x[0]) + +# res = [] +# start, end = intervals[0][0], intervals[0][1] +# for interval in intervals: +# s, e = interval[0], interval[1] + +# if s <= end: # overlap +# end = max(end, e) +# else: +# res.append([start, end]) +# start, end = s, e - res.append([start, end]) - return res \ No newline at end of file +# res.append([start, end]) +# return res From 7e7c62efb7bb9bee6f2b34e5a00ab410eb2dfbae Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:29:17 +0800 Subject: [PATCH 11/69] =?UTF-8?q?Update=200062-=E4=B8=8D=E5=90=8C=E8=B7=AF?= =?UTF-8?q?=E5=BE=84.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...15\345\220\214\350\267\257\345\276\204.py" | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git "a/0062.\344\270\215\345\220\214\350\267\257\345\276\204/0062-\344\270\215\345\220\214\350\267\257\345\276\204.py" "b/0062.\344\270\215\345\220\214\350\267\257\345\276\204/0062-\344\270\215\345\220\214\350\267\257\345\276\204.py" index 8c89221..4d3c1ba 100644 --- "a/0062.\344\270\215\345\220\214\350\267\257\345\276\204/0062-\344\270\215\345\220\214\350\267\257\345\276\204.py" +++ "b/0062.\344\270\215\345\220\214\350\267\257\345\276\204/0062-\344\270\215\345\220\214\350\267\257\345\276\204.py" @@ -1,18 +1,23 @@ -class Solution(object): - def uniquePaths(self, m, n): - """ - :type m: int - :type n: int - :rtype: int - """ - dp = [[0 for _ in range(m)]for _ in range(n)] - - for i in range(m): - dp[0][i] = 1 - for j in range(n): - dp[j][0] = 1 - - for i in range(1, n): - for j in range(1, m): - dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - return dp[-1][-1] \ No newline at end of file +# 数学解法:排列组合 +# 因为机器到底右下角,向下几步,向右几步都是固定的, +# 比如,m=3, n=2,我们只要向下 1 步,向右 2 步就一定能到达终点。 +# 所以有 C_{m+n-2}^{m-1} + +def uniquePaths(self, m: int, n: int) -> int: + return int(math.factorial(m+n-2)/math.factorial(m-1)/math.factorial(n-1)) + +# 动态规划 +# 动态方程:dp[i][j] = dp[i-1][j] + dp[i][j-1] +# 注意,对于第一行 dp[0][j],或者第一列 dp[i][0],由于都是在边界,所以只能为 1 +# 时间复杂度:O(m*n)O(m∗n) +# 空间复杂度:O(m * n)O(m∗n) +# 优化:因为我们每次只需要 dp[i-1][j],dp[i][j-1] + +class Solution: + def uniquePaths(self, m: int, n: int) -> int: + dp = [[1]*n] + [[1]+[0] * (n-1) for _ in range(m-1)] + #print(dp) + for i in range(1, m): + for j in range(1, n): + dp[i][j] = dp[i-1][j] + dp[i][j-1] + return dp[-1][-1] From d2fdd5d532c7bcb880db94133f806cb1acd0b1bd Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:34:38 +0800 Subject: [PATCH 12/69] =?UTF-8?q?Update=200064-=E6=9C=80=E5=B0=8F=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...17\350\267\257\345\276\204\345\222\214.py" | 90 +++++++++++++++---- 1 file changed, 73 insertions(+), 17 deletions(-) diff --git "a/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" "b/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" index 421b9bd..3a026a4 100644 --- "a/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" +++ "b/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" @@ -1,21 +1,77 @@ -class Solution(object): - def minPathSum(self, grid): - """ - :type grid: List[List[int]] - :rtype: int - """ - if not grid or not grid[0]: - return 0 - m, n = len(grid), len(grid[0]) +# 解题思路: +# 此题是典型的动态规划题目。 + +# 状态定义: + +# 设 dpdp 为大小 m \times nm×n 矩阵,其中 dp[i][j]dp[i][j] 的值代表直到走到 (i,j)(i,j) 的最小路径和。 +# 转移方程: + +# 题目要求,只能向右或向下走,换句话说,当前单元格 (i,j)(i,j) 只能从左方单元格 (i-1,j)(i−1,j) 或上方单元格 (i,j-1)(i,j−1) 走到,因此只需要考虑矩阵左边界和上边界。 + +# 走到当前单元格 (i,j)(i,j) 的最小路径和 == “从左方单元格 (i-1,j)(i−1,j) 与 从上方单元格 (i,j-1)(i,j−1) 走来的 两个最小路径和中较小的 ” ++ 当前单元格值 grid[i][j]grid[i][j] 。具体分为以下 44 种情况: +# 当左边和上边都不是矩阵边界时: 即当i \not= 0i +#  +# ​ +# =0, j \not= 0j +#  +# ​ +# =0时,dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]dp[i][j]=min(dp[i−1][j],dp[i][j−1])+grid[i][j] ; +# 当只有左边是矩阵边界时: 只能从上面来,即当i = 0, j \not= 0i=0,j +#  +# ​ +# =0时, dp[i][j] = dp[i][j - 1] + grid[i][j]dp[i][j]=dp[i][j−1]+grid[i][j] ; +# 当只有上边是矩阵边界时: 只能从左面来,即当i \not= 0, j = 0i +#  +# ​ +# =0,j=0时, dp[i][j] = dp[i - 1][j] + grid[i][j]dp[i][j]=dp[i−1][j]+grid[i][j] ; +# 当左边和上边都是矩阵边界时: 即当i = 0, j = 0i=0,j=0时,其实就是起点, dp[i][j] = grid[i][j]dp[i][j]=grid[i][j]; +# 初始状态: + +# dpdp 初始化即可,不需要修改初始 00 值。 +# 返回值: + +# 返回 dpdp 矩阵右下角值,即走到终点的最小路径和。 +# 其实我们完全不需要建立 dpdp 矩阵浪费额外空间,直接遍历 grid[i][j]grid[i][j] 修改即可。这是因为:grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j] ;原 gridgrid 矩阵元素中被覆盖为 dpdp 元素后(都处于当前遍历点的左上方),不会再被使用到。 + +# 复杂度分析: +# 时间复杂度 O(M \times N)O(M×N) : 遍历整个 gridgrid 矩阵元素。 +# 空间复杂度 O(1)O(1) : 直接修改原矩阵,不使用额外空间。 + + +class Solution: + def minPathSum(self, grid: [[int]]) -> int: + for i in range(len(grid)): + for j in range(len(grid[0])): + if i == j == 0: continue + elif i == 0: grid[i][j] = grid[i][j - 1] + grid[i][j] + elif j == 0: grid[i][j] = grid[i - 1][j] + grid[i][j] + else: grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j] + return grid[-1][-1] + +# 作者:jyd +# 链接:https://leetcode-cn.com/problems/minimum-path-sum/solution/zui-xiao-lu-jing-he-dong-tai-gui-hua-gui-fan-liu-c/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + + +# class Solution(object): +# def minPathSum(self, grid): +# """ +# :type grid: List[List[int]] +# :rtype: int +# """ +# if not grid or not grid[0]: +# return 0 +# m, n = len(grid), len(grid[0]) - for j in range(1, n): - grid[0][j] += grid[0][j - 1] +# for j in range(1, n): +# grid[0][j] += grid[0][j - 1] - for i in range(1, m): - grid[i][0] += grid[i - 1][0] +# for i in range(1, m): +# grid[i][0] += grid[i - 1][0] - for i in range(1, m): - for j in range(1, n): - grid[i][j] += min(grid[i - 1][j], grid[i][j - 1]) +# for i in range(1, m): +# for j in range(1, n): +# grid[i][j] += min(grid[i - 1][j], grid[i][j - 1]) - return grid[-1][-1] \ No newline at end of file +# return grid[-1][-1] From 9f2b56a299a8be6def0fb0d98234ba7975aee1bd Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:42:26 +0800 Subject: [PATCH 13/69] =?UTF-8?q?Update=200070-=E7=88=AC=E6=A5=BC=E6=A2=AF?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0-\347\210\254\346\245\274\346\242\257.py" | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git "a/0070.\347\210\254\346\245\274\346\242\257/0070-\347\210\254\346\245\274\346\242\257.py" "b/0070.\347\210\254\346\245\274\346\242\257/0070-\347\210\254\346\245\274\346\242\257.py" index 88ab0fc..90139ea 100644 --- "a/0070.\347\210\254\346\245\274\346\242\257/0070-\347\210\254\346\245\274\346\242\257.py" +++ "b/0070.\347\210\254\346\245\274\346\242\257/0070-\347\210\254\346\245\274\346\242\257.py" @@ -1,19 +1,13 @@ +# 倒推一下,假设当前位于第 n 阶,那么上一步可能在第 n-1 或者第 n-2 阶,分别需要爬 1 级台阶和 2 级台阶。 +# 那么,f(n) = f(n-1) + f(n-2), + class Solution(object): - def climbStairs(self, n): - """ - :type n: int - :rtype: int - """ - if n <= 2: - return [1, 2][n - 1] - first = 1 - second = 2 - cnt = 2 - while cnt < n: - cnt += 1 - cur = first + second - if cnt == n: - return cur - first = second - second = cur - \ No newline at end of file + # 一维dp,自底向上 + def climbStairs(self, n: int) -> int: + dp = [0] * (n + 1) + dp[0] = dp[1] = 1 + for i in range(2, n + 1): + dp[i] = dp[i - 1] + dp[i - 2] + return dp[-1] + + From 54b553abcfaded149481431572ed0e73107e360a Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 22:54:14 +0800 Subject: [PATCH 14/69] =?UTF-8?q?Update=200072-=E7=BC=96=E8=BE=91=E8=B7=9D?= =?UTF-8?q?=E7=A6=BB.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...26\350\276\221\350\267\235\347\246\273.py" | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git "a/0072.\347\274\226\350\276\221\350\267\235\347\246\273/0072-\347\274\226\350\276\221\350\267\235\347\246\273.py" "b/0072.\347\274\226\350\276\221\350\267\235\347\246\273/0072-\347\274\226\350\276\221\350\267\235\347\246\273.py" index 84662af..ac13f95 100644 --- "a/0072.\347\274\226\350\276\221\350\267\235\347\246\273/0072-\347\274\226\350\276\221\350\267\235\347\246\273.py" +++ "b/0072.\347\274\226\350\276\221\350\267\235\347\246\273/0072-\347\274\226\350\276\221\350\267\235\347\246\273.py" @@ -1,25 +1,59 @@ -class Solution(object): - def minDistance(self, word1, word2): - """ - :type word1: str - :type word2: str - :rtype: int - """ - #dp[i][j]ʾword1[:i + 1]word2[:j + 1]Ľ - l1, l2 = len(word1), len(word2) - dp = [[0 for _ in range(l2 + 1)] for _ in range(l1 + 1)] +dp[i][j] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数 + +所以, + +当 word1[i] == word2[j],dp[i][j] = dp[i-1][j-1]; + +当 word1[i] != word2[j],dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1 + +其中,dp[i-1][j-1] 表示替换操作,dp[i-1][j] 表示删除操作,dp[i][j-1] 表示插入操作。 +注意,针对第一行,第一列要单独考虑, +第一行,是 word1 为空变成 word2 最少步数,就是插入操作 +第一列,是 word2 为空,需要的最少步数,就是删除操作 + +class Solution: + def minDistance(self, word1: str, word2: str) -> int: + n1 = len(word1) + n2 = len(word2) + dp = [[0] * (n2 + 1) for _ in range(n1 + 1)] + # 第一行 + for j in range(1, n2 + 1): + dp[0][j] = dp[0][j-1] + 1 + # 第一列 + for i in range(1, n1 + 1): + dp[i][0] = dp[i-1][0] + 1 + for i in range(1, n1 + 1): + for j in range(1, n2 + 1): + if word1[i-1] == word2[j-1]: + dp[i][j] = dp[i-1][j-1] + else: + dp[i][j] = min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1] ) + 1 + #print(dp) + return dp[-1][-1] + + +# class Solution(object): +# def minDistance(self, word1, word2): +# """ +# :type word1: str +# :type word2: str +# :rtype: int +# """ +# #dp[i][j]±íʾword1[:i + 1]ºÍword2[:j + 1]µÄ½â +# l1, l2 = len(word1), len(word2) +# dp = [[0 for _ in range(l2 + 1)] for _ in range(l1 + 1)] - for i in range(l1 + 1): - dp[i][0] = i - for j in range(l2 + 1): - dp[0][j] = j +# for i in range(l1 + 1): +# dp[i][0] = i +# for j in range(l2 + 1): +# dp[0][j] = j - for i in range(1, l1 + 1): - for j in range(1, l2 + 1): - if word1[i - 1] == word2[j - 1]: - dp[i][j] = dp[i - 1][j - 1] - else: - dp[i][j] = 1 + min(dp[i - 1][j], dp[i - 1][j - 1], dp[i][j - 1]) - return dp[l1][l2] +# for i in range(1, l1 + 1): +# for j in range(1, l2 + 1): +# if word1[i - 1] == word2[j - 1]: +# dp[i][j] = dp[i - 1][j - 1] +# else: +# dp[i][j] = 1 + min(dp[i - 1][j], dp[i - 1][j - 1], dp[i][j - 1]) +# return dp[l1][l2] - \ No newline at end of file + From 98d78cd245abd9a48bdfab8fff87fac8e6c7e5d1 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Wed, 19 May 2021 23:07:31 +0800 Subject: [PATCH 15/69] =?UTF-8?q?Create=200076=20=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E8=A6=86=E7=9B=96=E5=AD=90=E4=B8=B2.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...06\347\233\226\345\255\220\344\270\262.py" | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 "0075.\351\242\234\350\211\262\345\210\206\347\261\273/0076 \346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.py" diff --git "a/0075.\351\242\234\350\211\262\345\210\206\347\261\273/0076 \346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.py" "b/0075.\351\242\234\350\211\262\345\210\206\347\261\273/0076 \346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.py" new file mode 100644 index 0000000..8563925 --- /dev/null +++ "b/0075.\351\242\234\350\211\262\345\210\206\347\261\273/0076 \346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.py" @@ -0,0 +1,54 @@ +题解 +滑动窗口的思想: +用i,j表示滑动窗口的左边界和右边界,通过改变i,j来扩展和收缩滑动窗口,可以想象成一个窗口在字符串上游走,当这个窗口包含的元素满足条件,即包含字符串T的所有元素,记录下这个滑动窗口的长度j-i+1,这些长度中的最小值就是要求的结果。 + +步骤一 +不断增加j使滑动窗口增大,直到窗口包含了T的所有元素 + +步骤二 +不断增加i使滑动窗口缩小,因为是要求最小字串,所以将不必要的元素排除在外,使长度减小,直到碰到一个必须包含的元素,这个时候不能再扔了,再扔就不满足条件了,记录此时滑动窗口的长度,并保存最小值 + +步骤三 +让i再增加一个位置,这个时候滑动窗口肯定不满足条件了,那么继续从步骤一开始执行,寻找新的满足条件的滑动窗口,如此反复,直到j超出了字符串S范围。 + +面临的问题: +如何判断滑动窗口包含了T的所有元素? +我们用一个字典need来表示当前滑动窗口中需要的各元素的数量,一开始滑动窗口为空,用T中各元素来初始化这个need,当滑动窗口扩展或者收缩的时候,去维护这个need字典,例如当滑动窗口包含某个元素,我们就让need中这个元素的数量减1,代表所需元素减少了1个;当滑动窗口移除某个元素,就让need中这个元素的数量加1。 +记住一点:need始终记录着当前滑动窗口下,我们还需要的元素数量,我们在改变i,j时,需同步维护need。 +值得注意的是,只要某个元素包含在滑动窗口中,我们就会在need中存储这个元素的数量,如果某个元素存储的是负数代表这个元素是多余的。比如当need等于{'A':-2,'C':1}时,表示当前滑动窗口中,我们有2个A是多余的,同时还需要1个C。这么做的目的就是为了步骤二中,排除不必要的元素,数量为负的就是不必要的元素,而数量为0表示刚刚好。 +回到问题中来,那么如何判断滑动窗口包含了T的所有元素?结论就是当need中所有元素的数量都小于等于0时,表示当前滑动窗口不再需要任何元素。 +优化 +如果每次判断滑动窗口是否包含了T的所有元素,都去遍历need看是否所有元素数量都小于等于0,这个会耗费O(k)O(k)的时间复杂度,k代表字典长度,最坏情况下,k可能等于len(S)。 +其实这个是可以避免的,我们可以维护一个额外的变量needCnt来记录所需元素的总数量,当我们碰到一个所需元素c,不仅need[c]的数量减少1,同时needCnt也要减少1,这样我们通过needCnt就可以知道是否满足条件,而无需遍历字典了。 +前面也提到过,need记录了遍历到的所有元素,而只有need[c]>0大于0时,代表c就是所需元素 + + +def minWindow(self, s: str, t: str) -> str: + need=collections.defaultdict(int) + for c in t: + need[c]+=1 + needCnt=len(t) + i=0 + res=(0,float('inf')) + for j,c in enumerate(s): + if need[c]>0: + needCnt-=1 + need[c]-=1 + if needCnt==0: #步骤一:滑动窗口包含了所有T元素 + while True: #步骤二:增加i,排除多余元素 + c=s[i] + if need[c]==0: + break + need[c]+=1 + i+=1 + if j-ilen(s) else s[res[0]:res[1]+1] #如果res始终没被更新过,代表无满足条件的结果 + +作者:Mcdull0921 +链接:https://leetcode-cn.com/problems/minimum-window-substring/solution/tong-su-qie-xiang-xi-de-miao-shu-hua-dong-chuang-k/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From cf6311e719199ff0f1849c9daaeb3cd31399fc1a Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 10:07:54 +0800 Subject: [PATCH 16/69] Create ziyi.md --- .../ziyi.md" | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 "0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" diff --git "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" new file mode 100644 index 0000000..43e5bdf --- /dev/null +++ "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" @@ -0,0 +1,18 @@ +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + left,right = 0,0 + res = 0 + if len(s) == 0: + return 0 + if s.count(s[0]) == len(s): + return 1 + if len(set(s)) == len(s): + return len(s) + while right < len(s): + if s[right] not in s[left:right]: + right +=1 + res = max(res,len(s[left:right])) + else: + while s[right] in s[left:right]: + left +=1 + return res From ab6726f6b08739ce264a1d424e75757ed18666ee Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 10:08:33 +0800 Subject: [PATCH 17/69] Update ziyi.md --- .../ziyi.md" | 2 ++ 1 file changed, 2 insertions(+) diff --git "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" index 43e5bdf..5510ee8 100644 --- "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" +++ "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/ziyi.md" @@ -16,3 +16,5 @@ class Solution: while s[right] in s[left:right]: left +=1 return res + +![image](https://github.com/zaie/LeetCode-Python/assets/17739876/5a4f060e-a10a-4587-89d2-d983f7fd411e) From 566c5dfa1e40ad28d57a1d143c24fb8da457f68d Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 10:11:10 +0800 Subject: [PATCH 18/69] =?UTF-8?q?Update=200003-=E6=97=A0=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E7=9A=84=E6=9C=80=E9=95=BF=E5=AD=90=E4=B8=B2?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\351\225\277\345\255\220\344\270\262.py" | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" index 8a1f7f4..ba73124 100644 --- "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" +++ "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" @@ -1,16 +1,19 @@ -class Solution(object): - def lengthOfLongestSubstring(self, s): - """ - :type s: str - :rtype: int - """ - left, right = 0, 0 - dic = dict() +# 双指针,如果有重复的就动左指针,否则就动右指针,记录最大长度 +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + left,right = 0,0 res = 0 + if len(s) == 0: + return 0 + if s.count(s[0]) == len(s): + return 1 + if len(set(s)) == len(s): + return len(s) while right < len(s): - if s[right] in dic: - left = max(left, dic[s[right]] + 1) - dic[s[right]] = right - res = max(res, right - left + 1) - right += 1 - return res \ No newline at end of file + if s[right] not in s[left:right]: + right +=1 + res = max(res,len(s[left:right])) + else: + while s[right] in s[left:right]: + left +=1 + return res From e70c2a3a26220c86ca417789bfe893904496b73d Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 10:21:24 +0800 Subject: [PATCH 19/69] =?UTF-8?q?Update=200003-=E6=97=A0=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E7=9A=84=E6=9C=80=E9=95=BF=E5=AD=90=E4=B8=B2?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" index ba73124..8ffefca 100644 --- "a/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" +++ "b/0003.\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262/0003-\346\227\240\351\207\215\345\244\215\345\255\227\347\254\246\347\232\204\346\234\200\351\225\277\345\255\220\344\270\262.py" @@ -1,4 +1,5 @@ -# 双指针,如果有重复的就动左指针,否则就动右指针,记录最大长度 +# 双指针,如果没有重复就扩大(就动左指针),记录最大长度 +# 否则就动右指针,直到没有重复为止 class Solution: def lengthOfLongestSubstring(self, s: str) -> int: left,right = 0,0 From 2be044b9d1a963449c8654f8edf12d9758067a93 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 11:02:33 +0800 Subject: [PATCH 20/69] =?UTF-8?q?Update=200004-=E5=AF=BB=E6=89=BE=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=9C=89=E5=BA=8F=E6=95=B0=E7=BB=84=E7=9A=84=E4=B8=AD?= =?UTF-8?q?=E4=BD=8D=E6=95=B0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...04\344\270\255\344\275\215\346\225\260.py" | 50 +++++++------------ 1 file changed, 17 insertions(+), 33 deletions(-) diff --git "a/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" "b/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" index a36ac3f..cdffd4b 100644 --- "a/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" +++ "b/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" @@ -1,35 +1,19 @@ -from heapq import * -class DoubleHeap(object): - def __init__(self): - self.maxh = [] - self.minh = [] - heapify(self.maxh) - heapify(self.minh) - - def insert(self, val): - heappush(self.minh, val) - heappush(self.maxh, -heappop(self.minh)) - if len(self.maxh) > len(self.minh): - heappush(self.minh, -heappop(self.maxh)) - - def findMedian(self): - if len(self.maxh) == len(self.minh): - return (self.minh[0] - self.maxh[0]) / 2.0 - return self.minh[0]/1.0 +# 假设 nums1[i-1]<=nums2[j] 且 nums2[j-1]<=nums1[i],nums1[:i] 和 nums2[:j] 就是最小的 i+j 个数 +# 当 i+j==(m+n)//2 时,即找到了最小的一半数,即可求出中位数 +# 因此遍历和为 (m+n)//2 的 对,找到满足 nums1[i-1]<=nums2[j] 且 nums2[j-1]<=nums1[i] 的即可 +# 注意 i 递增时,nums1[i-1]、nums1[i] 递增,nums2[j]、nums2[j-1] 递减,因此遍历找到第一个满足 nums2[j-1]<=nums1[i] 的即可。 +# 为了方便,当 m>n 时,可以交换 nums1、nums2 使得 m<=n,排除边界情况。 -class Solution(object): - def findMedianSortedArrays(self, nums1, nums2): - """ - :type nums1: List[int] - :type nums2: List[int] - :rtype: float - """ - dh = DoubleHeap() - for num in nums1: - dh.insert(num) - - for num in nums2: - dh.insert(num) - - return dh.findMedian() \ No newline at end of file +class Solution: + def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: + m, n = len(nums1), len(nums2) + if m > n: + return self.findMedianSortedArrays(nums2, nums1) + i, j = 0, (m+n) // 2 + while i < m and nums1[i] < nums2[j-1]: + i += 1 + j -= 1 + left = max(nums1[i-1] if i else float('-inf'), nums2[j-1] if j else float('-inf')) + right = min(nums1[i] if i Date: Thu, 1 Jun 2023 11:05:23 +0800 Subject: [PATCH 21/69] =?UTF-8?q?Update=200004-=E5=AF=BB=E6=89=BE=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=9C=89=E5=BA=8F=E6=95=B0=E7=BB=84=E7=9A=84=E4=B8=AD?= =?UTF-8?q?=E4=BD=8D=E6=95=B0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...204\344\270\255\344\275\215\346\225\260.py" | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git "a/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" "b/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" index cdffd4b..7ace030 100644 --- "a/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" +++ "b/0004.\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260/0004-\345\257\273\346\211\276\344\270\244\344\270\252\346\234\211\345\272\217\346\225\260\347\273\204\347\232\204\344\270\255\344\275\215\346\225\260.py" @@ -17,3 +17,21 @@ def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: left = max(nums1[i-1] if i else float('-inf'), nums2[j-1] if j else float('-inf')) right = min(nums1[i] if i Date: Thu, 1 Jun 2023 14:44:48 +0800 Subject: [PATCH 22/69] =?UTF-8?q?Update=200005-=E6=9C=80=E9=95=BF=E5=9B=9E?= =?UTF-8?q?=E6=96=87=E5=AD=90=E4=B8=B2.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...36\346\226\207\345\255\220\344\270\262.py" | 132 +++++++++++++++--- 1 file changed, 111 insertions(+), 21 deletions(-) diff --git "a/0005.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/0005-\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.py" "b/0005.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/0005-\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.py" index 8033cf5..cca42b4 100644 --- "a/0005.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/0005-\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.py" +++ "b/0005.\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262/0005-\346\234\200\351\225\277\345\233\236\346\226\207\345\255\220\344\270\262.py" @@ -1,24 +1,114 @@ -class Solution(object): - def longestPalindrome(self, s): - """ - :type s: str - :rtype: str - """ - res = "" - for i in range(len(s)): - tmp = self.centralSpread(i, i, s) - if len(tmp) > len(res): - res = tmp - tmp = self.centralSpread(i, i + 1, s) - if len(tmp) > len(res): - res = tmp - return res - - def centralSpread(self, left, right, s): - res = "" +对于一个子串而言,如果它是回文串,并且长度大于 222,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串 “ababa”\textrm{``ababa''}“ababa”,如果我们已经知道 “bab”\textrm{``bab''}“bab” 是回文串,那么 “ababa”\textrm{``ababa''}“ababa” 一定是回文串,这是因为它的首尾两个字母都是 “a”\textrm{``a''}“a”。 + +根据这样的思路,我们就可以用动态规划的方法解决本题。我们用 P(i,j)P(i,j)P(i,j) 表示字符串 sss 的第 iii 到 jjj 个字母组成的串(下文表示成 s[i:j]s[i:j]s[i:j])是否为回文串: + +P(i,j)={true,如果子串 Si…Sj 是回文串false,其它情况 P(i,j) = \begin{cases} \text{true,} &\quad\text{如果子串~} S_i \dots S_j \text{~是回文串}\\ \text{false,} &\quad\text{其它情况} \end{cases} +P(i,j)={ +true, +false, +​ + +如果子串 S +i +​ + …S +j +​ +  是回文串 +其它情况 +​ + +这里的「其它情况」包含两种可能性: + +s[i,j]s[i, j]s[i,j] 本身不是一个回文串; + +i>ji > ji>j,此时 s[i,j]s[i, j]s[i,j] 本身不合法。 + +那么我们就可以写出动态规划的状态转移方程: + +P(i,j)=P(i+1,j−1)∧(Si==Sj) P(i, j) = P(i+1, j-1) \wedge (S_i == S_j) +P(i,j)=P(i+1,j−1)∧(S +i +​ + ==S +j +​ + ) +也就是说,只有 s[i+1:j−1]s[i+1:j-1]s[i+1:j−1] 是回文串,并且 sss 的第 iii 和 jjj 个字母相同时,s[i:j]s[i:j]s[i:j] 才会是回文串。 + +上文的所有讨论是建立在子串长度大于 222 的前提之上的,我们还需要考虑动态规划中的边界条件,即子串的长度为 111 或 222。对于长度为 111 的子串,它显然是个回文串;对于长度为 222 的子串,只要它的两个字母相同,它就是一个回文串。因此我们就可以写出动态规划的边界条件: + +{P(i,i)=trueP(i,i+1)=(Si==Si+1) \begin{cases} P(i, i) = \text{true} \\ P(i, i+1) = ( S_i == S_{i+1} ) \end{cases} +{ +P(i,i)=true +P(i,i+1)=(S +i +​ + ==S +i+1 +​ + ) +​ + +根据这个思路,我们就可以完成动态规划了,最终的答案即为所有 P(i,j)=trueP(i, j) = \text{true}P(i,j)=true 中 j−i+1j-i+1j−i+1(即子串长度)的最大值。注意:在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序。 + +class Solution: + def longestPalindrome(self, s: str) -> str: + n = len(s) + if n < 2: + return s + + max_len = 1 + begin = 0 + # dp[i][j] 表示 s[i..j] 是否是回文串 + dp = [[False] * n for _ in range(n)] + for i in range(n): + dp[i][i] = True + + # 递推开始 + # 先枚举子串长度 + for L in range(2, n + 1): + # 枚举左边界,左边界的上限设置可以宽松一些 + for i in range(n): + # 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得 + j = L + i - 1 + # 如果右边界越界,就可以退出当前循环 + if j >= n: + break + + if s[i] != s[j]: + dp[i][j] = False + else: + if j - i < 3: + dp[i][j] = True + else: + dp[i][j] = dp[i + 1][j - 1] + + # 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置 + if dp[i][j] and j - i + 1 > max_len: + max_len = j - i + 1 + begin = i + return s[begin:begin + max_len] + +# 可以发现,所有的状态在转移的时候的可能性都是唯一的。也就是说,我们可以从每一种边界情况开始「扩展」,也可以得出所有的状态对应的答案。 + +# 边界情况即为子串长度为 111 或 222 的情况。我们枚举每一种边界情况,并从对应的子串开始不断地向两边扩展。如果两边的字母相同,我们就可以继续扩展,例如从 P(i+1,j−1)P(i+1,j-1)P(i+1,j−1) 扩展到 P(i,j)P(i,j)P(i,j);如果两边的字母不同,我们就可以停止扩展,因为在这之后的子串都不能是回文串了。 + +# 聪明的读者此时应该可以发现,「边界情况」对应的子串实际上就是我们「扩展」出的回文串的「回文中心」。方法二的本质即为:我们枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。我们对所有的长度求出最大值,即可得到最终的答案。 +class Solution: + def expandAroundCenter(self, s, left, right): while left >= 0 and right < len(s) and s[left] == s[right]: - res = s[left: right + 1] left -= 1 right += 1 - # print res, left, right - return res \ No newline at end of file + return left + 1, right - 1 + + def longestPalindrome(self, s: str) -> str: + start, end = 0, 0 + for i in range(len(s)): + left1, right1 = self.expandAroundCenter(s, i, i) + left2, right2 = self.expandAroundCenter(s, i, i + 1) + if right1 - left1 > end - start: + start, end = left1, right1 + if right2 - left2 > end - start: + start, end = left2, right2 + return s[start: end + 1] From 03c93344f4e4ff33c3fda89c29e8a93c7ed9c791 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 17:03:15 +0800 Subject: [PATCH 23/69] =?UTF-8?q?Update=200011-=E7=9B=9B=E6=9C=80=E5=A4=9A?= =?UTF-8?q?=E6=B0=B4=E7=9A=84=E5=AE=B9=E5=99=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...64\347\232\204\345\256\271\345\231\250.py" | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git "a/0011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/0011-\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" "b/0011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/0011-\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" index 15c142d..b57d9fd 100644 --- "a/0011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/0011-\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" +++ "b/0011.\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250/0011-\347\233\233\346\234\200\345\244\232\346\260\264\347\232\204\345\256\271\345\231\250.py" @@ -1,16 +1,25 @@ -class Solution(object): - def maxArea(self, height): - """ - :type height: List[int] - :rtype: int - """ - left, right = 0, len(height) - 1 - res = 0 - while(left < right): - # print left, right, - res = max(res, (right - left) * min(height[left], height[right])) - if height[left] < height[right]: - left += 1 +在每个状态下,无论长板或短板向中间收窄一格,都会导致水槽 底边宽度 −1-1−1​ 变短: + +若向内 移动短板 ,水槽的短板 min(h[i],h[j])min(h[i], h[j])min(h[i],h[j]) 可能变大,因此下个水槽的面积 可能增大 。 +若向内 移动长板 ,水槽的短板 min(h[i],h[j])min(h[i], h[j])min(h[i],h[j])​ 不变或变小,因此下个水槽的面积 一定变小 。 +因此,初始化双指针分列水槽左右两端,循环每轮将短板向内移动一格,并更新面积最大值,直到两指针相遇时跳出;即可获得最大面积。 + +算法流程: +初始化: 双指针 iii , jjj 分列水槽左右两端; +循环收窄: 直至双指针相遇时跳出; +更新面积最大值 resresres ; +选定两板高度中的短板,向中间收窄一格; +返回值: 返回面积最大值 resresres 即可; + + +class Solution: + def maxArea(self, height: List[int]) -> int: + i, j, res = 0, len(height) - 1, 0 + while i < j: + if height[i] < height[j]: + res = max(res, height[i] * (j - i)) + i += 1 else: - right -= 1 - return res \ No newline at end of file + res = max(res, height[j] * (j - i)) + j -= 1 + return res From 84f5004539a4b3e82cb3f47cb6270516d0eb67fc Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 17:07:57 +0800 Subject: [PATCH 24/69] =?UTF-8?q?Update=200015-=E4=B8=89=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...11\346\225\260\344\271\213\345\222\214.py" | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git "a/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" "b/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" index ffe7ff2..95d1b77 100644 --- "a/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" +++ "b/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" @@ -1,33 +1,34 @@ -class Solution(object): - def threeSum(self, nums): - """ - :type nums: List[int] - :rtype: List[List[int]] - """ +双指针法铺垫: 先将给定 nums 排序,复杂度为 O(NlogN)O(NlogN)O(NlogN)。 +双指针法思路: 固定 333 个指针中最左(最小)数字的指针 k,双指针 i,j 分设在数组索引 (k,len(nums))(k, len(nums))(k,len(nums)) 两端,通过双指针交替向中间移动,记录对于每个固定指针 k 的所有满足 nums[k] + nums[i] + nums[j] == 0 的 i,j 组合: +当 nums[k] > 0 时直接break跳出:因为 nums[j] >= nums[i] >= nums[k] > 0,即 333 个数字都大于 000 ,在此固定指针 k 之后不可能再找到结果了。 +当 k > 0且nums[k] == nums[k - 1]时即跳过此元素nums[k]:因为已经将 nums[k - 1] 的所有组合加入到结果中,本次双指针搜索只会得到重复组合。 +i,j 分设在数组索引 (k,len(nums))(k, len(nums))(k,len(nums)) 两端,当i < j时循环计算s = nums[k] + nums[i] + nums[j],并按照以下规则执行双指针移动: +当s < 0时,i += 1并跳过所有重复的nums[i]; +当s > 0时,j -= 1并跳过所有重复的nums[j]; +当s == 0时,记录组合[k, i, j]至res,执行i += 1和j -= 1并跳过所有重复的nums[i]和nums[j],防止记录到重复组合。 + + +class Solution: + def threeSum(self, nums: [int]) -> [[int]]: nums.sort() - res = [] - for i, num in enumerate(nums): - if i == 0 or nums[i] > nums[i - 1]: - # num + b + c == 0 - left = i + 1 - right = len(nums) - 1 - - while(left < right): - s = num + nums[left] + nums[right] - if s == 0: - res.append([num, nums[left], nums[right]]) - left += 1 - right -= 1 - while(left < right and nums[left] == nums[left - 1]): - left += 1 - while(left < right and nums[right + 1] == nums[right]): - right -= 1 - # break - elif s > 0: - right -= 1 - else: - left += 1 - - + res, k = [], 0 + for k in range(len(nums) - 2): + if nums[k] > 0: break # 1. because of j > i > k. + if k > 0 and nums[k] == nums[k - 1]: continue # 2. skip the same `nums[k]`. + i, j = k + 1, len(nums) - 1 + while i < j: # 3. double pointer + s = nums[k] + nums[i] + nums[j] + if s < 0: + i += 1 + while i < j and nums[i] == nums[i - 1]: i += 1 + elif s > 0: + j -= 1 + while i < j and nums[j] == nums[j + 1]: j -= 1 + else: + res.append([nums[k], nums[i], nums[j]]) + i += 1 + j -= 1 + while i < j and nums[i] == nums[i - 1]: i += 1 + while i < j and nums[j] == nums[j + 1]: j -= 1 return res - \ No newline at end of file + From 02b71418ee6178ff929a0b5ca7e3c68505563625 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 17:19:46 +0800 Subject: [PATCH 25/69] =?UTF-8?q?Update=200015-=E4=B8=89=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git "a/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" "b/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" index 95d1b77..7294a6b 100644 --- "a/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" +++ "b/0015.\344\270\211\346\225\260\344\271\213\345\222\214/0015-\344\270\211\346\225\260\344\271\213\345\222\214.py" @@ -1,5 +1,6 @@ 双指针法铺垫: 先将给定 nums 排序,复杂度为 O(NlogN)O(NlogN)O(NlogN)。 -双指针法思路: 固定 333 个指针中最左(最小)数字的指针 k,双指针 i,j 分设在数组索引 (k,len(nums))(k, len(nums))(k,len(nums)) 两端,通过双指针交替向中间移动,记录对于每个固定指针 k 的所有满足 nums[k] + nums[i] + nums[j] == 0 的 i,j 组合: +双指针法思路: 固定 333 个指针中最左(最小)数字的指针 k,双指针 i,j 分设在数组索引 (k,len(nums))(k, len(nums))(k,len(nums)) 两端, +通过双指针交替向中间移动,记录对于每个固定指针 k 的所有满足 nums[k] + nums[i] + nums[j] == 0 的 i,j 组合: 当 nums[k] > 0 时直接break跳出:因为 nums[j] >= nums[i] >= nums[k] > 0,即 333 个数字都大于 000 ,在此固定指针 k 之后不可能再找到结果了。 当 k > 0且nums[k] == nums[k - 1]时即跳过此元素nums[k]:因为已经将 nums[k - 1] 的所有组合加入到结果中,本次双指针搜索只会得到重复组合。 i,j 分设在数组索引 (k,len(nums))(k, len(nums))(k,len(nums)) 两端,当i < j时循环计算s = nums[k] + nums[i] + nums[j],并按照以下规则执行双指针移动: From b3a30cf6eec25ea5f5addb0677e077aebb7b71db Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 17:47:44 +0800 Subject: [PATCH 26/69] =?UTF-8?q?Update=200017-=E7=94=B5=E8=AF=9D=E5=8F=B7?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E5=AD=97=E6=AF=8D=E7=BB=84=E5=90=88.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...27\346\257\215\347\273\204\345\220\210.py" | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git "a/0017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/0017-\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" "b/0017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/0017-\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" index 935f397..8b8a9fd 100644 --- "a/0017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/0017-\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" +++ "b/0017.\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210/0017-\347\224\265\350\257\235\345\217\267\347\240\201\347\232\204\345\255\227\346\257\215\347\273\204\345\220\210.py" @@ -1,22 +1,29 @@ -class Solution(object): - def letterCombinations(self, digits): - """ - :type digits: str - :rtype: List[str] - """ - if not digits: - return [] - mapping = {2:"abc", 3:"def", 4:"ghi", 5:"jkl", 6:"mno", 7:"pqrs", 8:"tuv", 9:"wxyz"} - +当题目中出现 “所有组合” 等类似字眼时,我们第一感觉就要想到用回溯。 + +定义函数 backtrack(combination, nextdigit),当 nextdigit 非空时,对于 nextdigit[0] 中的每一个字母 letter, +执行回溯 backtrack(combination + letter,nextdigit[1:],直至 nextdigit 为空。最后将 combination 加入到结果中。 + + +class Solution: + def letterCombinations(self, digits: str) -> List[str]: + if not digits: return [] + + phone = {'2':['a','b','c'], + '3':['d','e','f'], + '4':['g','h','i'], + '5':['j','k','l'], + '6':['m','n','o'], + '7':['p','q','r','s'], + '8':['t','u','v'], + '9':['w','x','y','z']} + + def backtrack(conbination,nextdigit): + if len(nextdigit) == 0: + res.append(conbination) + else: + for letter in phone[nextdigit[0]]: + backtrack(conbination + letter,nextdigit[1:]) + res = [] - # for i, digit in enumerate(digits) - def dfs(nums, tmp): - if not nums: - res.append(tmp) - return - - for char in mapping[int(nums[0])]: - dfs(nums[1:], tmp + char) - - dfs(digits, "") - return res \ No newline at end of file + backtrack('',digits) + return res From 56d123703ea593535ea1c9f873aafdde0373b14a Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 17:57:30 +0800 Subject: [PATCH 27/69] =?UTF-8?q?Update=200020-=E6=9C=89=E6=95=88=E7=9A=84?= =?UTF-8?q?=E6=8B=AC=E5=8F=B7.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...10\347\232\204\346\213\254\345\217\267.py" | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git "a/0020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/0020-\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" "b/0020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/0020-\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" index 563ad92..46b2ea0 100644 --- "a/0020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/0020-\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" +++ "b/0020.\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267/0020-\346\234\211\346\225\210\347\232\204\346\213\254\345\217\267.py" @@ -1,16 +1,35 @@ -class Solution(object): - def isValid(self, s): - """ - :type s: str - :rtype: bool - """ - dic = {")": "(", "]":"[", "}":"{"} - stack = [] - for ch in s: - if ch in ["(", "[", "{"]: - stack.append(ch) - else: - if not stack or dic[ch] != stack[-1]: - return False - stack.pop() - return len(stack) == 0 \ No newline at end of file +算法原理 + +栈先入后出特点恰好与本题括号排序特点一致,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,则遍历完所有括号后 stack 仍然为空; +建立哈希表 dic 构建左右括号对应关系:keykeykey 左括号,valuevaluevalue 右括号;这样查询 222 个括号是否对应只需 O(1)O(1)O(1) 时间复杂度;建立栈 stack,遍历字符串 s 并按照算法流程一一判断。 +算法流程 + +如果 c 是左括号,则入栈 pushpushpush; +否则通过哈希表判断括号对应关系,若 stack 栈顶出栈括号 stack.pop() 与当前遍历括号 c 不对应,则提前返回 falsefalsefalse。 +提前返回 falsefalsefalse + +提前返回优点: 在迭代过程中,提前发现不符合的括号并且返回,提升算法效率。 +解决边界问题: +栈 stack 为空: 此时 stack.pop() 操作会报错;因此,我们采用一个取巧方法,给 stack 赋初值 ??? ,并在哈希表 dic 中建立 key:′?′,value:′?′key: '?',value:'?'key: +′ + ? +′ + ,value: +′ + ? +′ + 的对应关系予以配合。此时当 stack 为空且 c 为右括号时,可以正常提前返回 falsefalsefalse; +字符串 s 以左括号结尾: 此情况下可以正常遍历完整个 s,但 stack 中遗留未出栈的左括号;因此,最后需返回 len(stack) == 1,以判断是否是有效的括号组合。 +复杂度分析 + +时间复杂度 O(N)O(N)O(N):正确的括号组合需要遍历 111 遍 s; +空间复杂度 O(N)O(N)O(N):哈希表和栈使用线性的空间大小。 + +class Solution: + def isValid(self, s: str) -> bool: + dic = {'{': '}', '[': ']', '(': ')', '?': '?'} + stack = ['?'] + for c in s: + if c in dic: stack.append(c) + elif dic[stack.pop()] != c: return False + return len(stack) == 1 From d5bc1e27cf9ae40aa5daebc3e6ccab1348a613fa Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Thu, 1 Jun 2023 18:03:31 +0800 Subject: [PATCH 28/69] =?UTF-8?q?Update=200021-=E5=90=88=E5=B9=B6=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=9C=89=E5=BA=8F=E9=93=BE=E8=A1=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...11\345\272\217\351\223\276\350\241\250.py" | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git "a/0021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/0021-\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" "b/0021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/0021-\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" index 7e7be51..6eede54 100644 --- "a/0021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/0021-\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" +++ "b/0021.\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250/0021-\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.py" @@ -1,9 +1,10 @@ +保存头指针,移动当前指针,比较大小,最后将还没遍历完的直接接上 + # Definition for singly-linked list. # class ListNode(object): -# def __init__(self, x): -# self.val = x -# self.next = None - +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next class Solution(object): def mergeTwoLists(self, l1, l2): """ @@ -11,23 +12,18 @@ def mergeTwoLists(self, l1, l2): :type l2: ListNode :rtype: ListNode """ - dummy = ListNode(-1) - - p = dummy - + cur = ListNode() + temp = cur # 保存头指针,移动的是cur指针 while l1 and l2: if l1.val <= l2.val: - p.next = ListNode(l1.val) + cur.next = l1 l1 = l1.next - else: - p.next = ListNode(l2.val) + elif l1.val > l2.val: + cur.next = l2 l2 = l2.next - p = p.next - - if l1: - p.next = l1 - - if l2: - p.next = l2 - - return dummy.next \ No newline at end of file + cur = cur.next + if l1 is not None: + cur.next = l1 + elif l2 is not None: + cur.next = l2 + return temp.next From 0202437c2d322dac060e1acc4bba61e92cdf27ea Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Fri, 2 Jun 2023 11:32:21 +0800 Subject: [PATCH 29/69] =?UTF-8?q?Update=200031-=E4=B8=8B=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8E=92=E5=88=97.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\344\270\252\346\216\222\345\210\227.py" | 53 +++++++++---------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git "a/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" "b/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" index 0d6deaf..0ea0e40 100644 --- "a/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" +++ "b/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" @@ -1,32 +1,27 @@ -# class Solution(object): -# def nextPermutation(self, nums): -# """ -# :type nums: List[int] -# :rtype: None Do not return anything, modify nums in-place instead. -# """ -# if not nums or len(nums) == 1: -# return nums -# # print nums, sorted(nums)[::-1] -# if nums == sorted(nums)[::-1]: -# nums[:] = nums[::-1] -# return - -# i = len(nums) - 1 -# while(i - 1 >= 0 and nums[i - 1] >= nums[i]): -# i -= 1 -# i -= 1 -# tmp = nums[i] -# j = len(nums) - 1 -# while(j >= i and nums[j] <= tmp): -# j -= 1 -# if nums[j] > tmp: -# break - -# # print tmp, nums[j], nums[i] -# nums[i], nums[j] = nums[j], nums[i] -# # print nums -# nums[i+ 1:] = nums[i + 1:][::-1] -# return +注意到下一个排列总是比当前排列要大,除非该排列已经是最大的排列。我们希望找到一种方法,能够找到一个大于当前序列的新序列,且变大的幅度尽可能小。具体地: + +我们需要将一个左边的「较小数」与一个右边的「较大数」交换,以能够让当前排列变大,从而得到下一个排列。 + +同时我们要让这个「较小数」尽量靠右,而「较大数」尽可能小。当交换完成后,「较大数」右边的数需要按照升序重新排列。这样可以在保证新排列大于原来排列的情况下,使变大的幅度尽可能小。 + +以排列 [4,5,2,6,3,1][4,5,2,6,3,1][4,5,2,6,3,1] 为例: + +我们能找到的符合条件的一对「较小数」与「较大数」的组合为 222 与 333,满足「较小数」尽量靠右,而「较大数」尽可能小。 + +当我们完成交换后排列变为 [4,5,3,6,2,1][4,5,3,6,2,1][4,5,3,6,2,1],此时我们可以重排「较小数」右边的序列,序列变为 [4,5,3,1,2,6][4,5,3,1,2,6][4,5,3,1,2,6]。 + +具体地,我们这样描述该算法,对于长度为 nnn 的排列 aaa: + +首先从后向前查找第一个顺序对 (i,i+1)(i,i+1)(i,i+1),满足 a[i] None: From c28ff6cf155f5f17b3ee00a018c95c80d87288e7 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Fri, 2 Jun 2023 11:32:39 +0800 Subject: [PATCH 30/69] =?UTF-8?q?Update=200031-=E4=B8=8B=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8E=92=E5=88=97.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\213\344\270\200\344\270\252\346\216\222\345\210\227.py" | 5 ----- 1 file changed, 5 deletions(-) diff --git "a/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" "b/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" index 0ea0e40..57945b4 100644 --- "a/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" +++ "b/0031.\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227/0031-\344\270\213\344\270\200\344\270\252\346\216\222\345\210\227.py" @@ -18,11 +18,6 @@ 交换 a[i]a[i]a[i] 与 a[j]a[j]a[j],此时可以证明区间 [i+1,n)[i+1,n)[i+1,n) 必为降序。我们可以直接使用双指针反转区间 [i+1,n)[i+1,n)[i+1,n) 使其变为升序,而无需对该区间进行排序。 -作者:力扣官方题解 -链接:https://leetcode.cn/problems/next-permutation/solutions/479151/xia-yi-ge-pai-lie-by-leetcode-solution/ -来源:力扣(LeetCode) -著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 - class Solution: def nextPermutation(self, nums: List[int]) -> None: i = len(nums) - 2 From ec6ee54bd236c521c3a8bd519f73cd7a196ac42d Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Fri, 2 Jun 2023 11:40:34 +0800 Subject: [PATCH 31/69] =?UTF-8?q?Update=200039-=E7=BB=84=E5=90=88=E6=80=BB?= =?UTF-8?q?=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...04\345\220\210\346\200\273\345\222\214.py" | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git "a/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" "b/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" index 20f1d1f..199a049 100644 --- "a/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" +++ "b/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" @@ -1,26 +1,27 @@ -class Solution(object): - def combinationSum(self, candidates, target): - """ - :type candidates: List[int] - :type target: int - :rtype: List[List[int]] - """ - res = [] - candidates.sort() - def dfs(t, tmp): - if t < 0: - return - if t == 0: - tmp.sort() - if tmp not in res: - res.append(tmp) - return - - for i, x in enumerate(candidates): - if t - x < 0: - break - dfs(t - x, tmp + [x]) - - - dfs(target, []) - return res \ No newline at end of file +变量意义:use表示已经使用过的数(组成的列表),remain表示距离target还有多大。 + +对candidates升序排序,以方便根据remain的大小使用return减小搜索空间; +递归求可能的组合。具体的,每次递归时对所有candidates做一次遍历,情况有3:1,满足条件,则答案加入一条;2,不足,继续递归,3,超出,则直接退出本路线。 +注意每层递归都对全体candidates做遍历会导致如[2,2,3],[3,2,2]这样的对称重复的答案的产生。这是因为发生了“往前选择”的情况,我们每次更深层的递归都往后缩小一个candidates,强制函数只能“往后选择”,这将不会出现重复答案。 +代码写的比较简单,更多细节请看代码 + + +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + candidates = sorted(candidates) + + ans = [] + + def find(s, use, remain): + for i in range(s, len(candidates)): + c = candidates[i] + if c == remain: + ans.append(use + [c]) + if c < remain: + find(i, use + [c], remain - c) + if c > remain: + return + find(0, [], target) + + return ans + From 49bb4babfaec3a77da512b001caef7f23b1d86cb Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Fri, 2 Jun 2023 11:52:42 +0800 Subject: [PATCH 32/69] =?UTF-8?q?Update=200046-=E5=85=A8=E6=8E=92=E5=88=97?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0046-\345\205\250\346\216\222\345\210\227.py" | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git "a/0046.\345\205\250\346\216\222\345\210\227/0046-\345\205\250\346\216\222\345\210\227.py" "b/0046.\345\205\250\346\216\222\345\210\227/0046-\345\205\250\346\216\222\345\210\227.py" index f2a991c..8fa2dec 100644 --- "a/0046.\345\205\250\346\216\222\345\210\227/0046-\345\205\250\346\216\222\345\210\227.py" +++ "b/0046.\345\205\250\346\216\222\345\210\227/0046-\345\205\250\346\216\222\345\210\227.py" @@ -1,3 +1,7 @@ +def permute(self, nums: List[int]) -> List[List[int]]: + return list(itertools.permutations(nums)) + + class Solution(object): def permute(self, nums): """ @@ -13,4 +17,4 @@ def dfs(tmp, nums): dfs(tmp + [x], nums[:i] + nums[i + 1:]) dfs([], nums) - return res \ No newline at end of file + return res From 5e973fa870adc9eb35e6356c37c5f05e60ce91c0 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Fri, 2 Jun 2023 11:58:25 +0800 Subject: [PATCH 33/69] =?UTF-8?q?Update=200048-=E6=97=8B=E8=BD=AC=E5=9B=BE?= =?UTF-8?q?=E5=83=8F.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...13\350\275\254\345\233\276\345\203\217.py" | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git "a/0048.\346\227\213\350\275\254\345\233\276\345\203\217/0048-\346\227\213\350\275\254\345\233\276\345\203\217.py" "b/0048.\346\227\213\350\275\254\345\233\276\345\203\217/0048-\346\227\213\350\275\254\345\233\276\345\203\217.py" index e97f740..f0acce4 100644 --- "a/0048.\346\227\213\350\275\254\345\233\276\345\203\217/0048-\346\227\213\350\275\254\345\233\276\345\203\217.py" +++ "b/0048.\346\227\213\350\275\254\345\233\276\345\203\217/0048-\346\227\213\350\275\254\345\233\276\345\203\217.py" @@ -1,20 +1,14 @@ -class Solution(object): - def rotate(self, matrix): - """ - :type matrix: List[List[int]] - :rtype: None Do not return anything, modify matrix in-place instead. - """ - #תҶԳƷת - if not matrix or not matrix[0]: - return matrix +class Solution: + def rotate(self, matrix: List[List[int]]) -> None: n = len(matrix) - + # 深拷贝 matrix -> tmp + tmp = copy.deepcopy(matrix) + # 根据元素旋转公式,遍历修改原矩阵 matrix 的各元素 for i in range(n): - for j in range(i + 1, n): - matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] - - for row in matrix: - for i in range(n // 2): - row[i], row[n - 1 - i] = row[n - 1 - i], row[i] - - return matrix \ No newline at end of file + for j in range(n): + matrix[j][n - 1 - i] = tmp[i][j] + +作者:Krahets +链接:https://leetcode.cn/problems/rotate-image/solutions/1228078/48-xuan-zhuan-tu-xiang-fu-zhu-ju-zhen-yu-jobi/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 1875dc4cf85f6e1e22b2b98fd9397f6a77133cc9 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 15:53:50 +0800 Subject: [PATCH 34/69] =?UTF-8?q?Update=200022-=E6=8B=AC=E5=8F=B7=E7=94=9F?= =?UTF-8?q?=E6=88=90.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...54\345\217\267\347\224\237\346\210\220.py" | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git "a/0022.\346\213\254\345\217\267\347\224\237\346\210\220/0022-\346\213\254\345\217\267\347\224\237\346\210\220.py" "b/0022.\346\213\254\345\217\267\347\224\237\346\210\220/0022-\346\213\254\345\217\267\347\224\237\346\210\220.py" index 326c241..48224d4 100644 --- "a/0022.\346\213\254\345\217\267\347\224\237\346\210\220/0022-\346\213\254\345\217\267\347\224\237\346\210\220.py" +++ "b/0022.\346\213\254\345\217\267\347\224\237\346\210\220/0022-\346\213\254\345\217\267\347\224\237\346\210\220.py" @@ -1,22 +1,51 @@ -class Solution(object): - def generateParenthesis(self, n): - """ - :type n: int - :rtype: List[str] - """ - +# 出图之后,我发现这其实就是一个满二叉树,我们只需要DFS所有节点即可。 + +# class Solution: +# def generateParenthesis(self, n: int) -> List[str]: +# if n <= 0: return [] +# res = [] + +# def dfs(paths): +# if len(paths) == n * 2: # 因为括号都是成对出现的 +# res.append(paths) +# return + +# dfs(paths + '(') +# dfs(paths + ')') + +# dfs('') +# return res +# 输出的结果如下 ['((((', '((()', '(()(', '(())', '()((', '()()', '())(', '()))', ')(((', ')(()', ')()(', ')())', '))((', '))()', ')))(', '))))'] 我们发现有一些结果是我们不需要的,比如((((,比如)))) 观察不需要的括号特点,((((实际上已经超过n了,我们生成同一方向的括号只需要n个即可,在生成的时候我们要限制住左括号与右括号生成的数量 + +# 这时我增加了left与right参数,分别代表左括号与右括号的数量,每生成一个我就增加一个。 + +# 那结束DFS的条件首先就需要把不符合的给过滤掉, ( > n 或 ) > n 或 ) > ( +# 当然 ) > n 这个条件也可以没有,因为 ) > ( 条件已经给控制住了。 + +# def dfs(paths, left, right): +# if left > n or right > left: return +# if len(paths) == n * 2: # 因为括号都是成对出现的 +# res.append(paths) +# return + +# dfs(paths + '(', left + 1, right) # 生成一个就加一个 +# dfs(paths + ')', left, right + 1) +# ['((()))', '(()())', '(())()', '()(())', '()()()'] + +# 代码 +class Solution: + def generateParenthesis(self, n: int) -> List[str]: + if n <= 0: return [] res = [] - - def dfs(tmp, left, right): - if len(tmp) == 2 * n: - res.append(tmp) - - if left: - dfs(tmp + "(", left - 1, right) - if right > left: - dfs(tmp + ")", left, right - 1) - - - dfs("", n, n) + + def dfs(paths, left, right): + if left > n or right > left: return + if len(paths) == n * 2: # 因为括号都是成对出现的 + res.append(paths) + return + + dfs(paths + '(', left + 1, right) # 生成一个就加一个 + dfs(paths + ')', left, right + 1) + + dfs('', 0, 0) return res - \ No newline at end of file From e3f9969e8a9d07a3a4029f1ba4ce2b2c44c4a6ce Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 15:59:47 +0800 Subject: [PATCH 35/69] =?UTF-8?q?Update=200023-=E5=90=88=E5=B9=B6K?= =?UTF-8?q?=E4=B8=AA=E6=8E=92=E5=BA=8F=E9=93=BE=E8=A1=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...22\345\272\217\351\223\276\350\241\250.py" | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git "a/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" "b/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" index dd6a0a5..c073546 100644 --- "a/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" +++ "b/0023.\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250/0023-\345\220\210\345\271\266K\344\270\252\346\216\222\345\272\217\351\223\276\350\241\250.py" @@ -58,4 +58,31 @@ def mergeTwoLists(self,l1, l2): else: l2.next = self.mergeTwoLists(l1, l2.next) return l2 + +# 应该和上面一个相同 +class Solution: + def mergeKLists(self, lists: List[ListNode]) -> ListNode: + if not lists: return None + res = None #设置初始结果为空 + for listi in lists: #逐个遍历 两两合并 + res = self.mergeTwoLists(res, listi) + return res + def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: + dummy = ListNode(0) #构造虚节点 + move = dummy #设置移动节点等于虚节点 + while l1 and l2: #都不空时 + if l1.val < l2.val: + move.next = l1 #移动节点指向数小的链表 + l1 = l1.next + else: + move.next = l2 + l2 = l2.next + move = move.next + move.next = l1 if l1 else l2 #连接后续非空链表 + return dummy.next #虚节点仍在开头 + +# 作者:千想 +# 链接:https://leetcode.cn/problems/merge-k-sorted-lists/solutions/1046759/python-23he-bing-kge-sheng-xu-lian-biao-ep54a/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 74d6832d6b72804a0adf4e26de2c3f8cd749fcdc Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 16:11:13 +0800 Subject: [PATCH 36/69] =?UTF-8?q?Update=200039-=E7=BB=84=E5=90=88=E6=80=BB?= =?UTF-8?q?=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...9-\347\273\204\345\220\210\346\200\273\345\222\214.py" | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git "a/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" "b/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" index 199a049..5fc8732 100644 --- "a/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" +++ "b/0039.\347\273\204\345\220\210\346\200\273\345\222\214/0039-\347\273\204\345\220\210\346\200\273\345\222\214.py" @@ -12,13 +12,13 @@ def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: ans = [] - def find(s, use, remain): - for i in range(s, len(candidates)): + def find(start_idx, used, remain): + for i in range(start_idx, len(candidates)): c = candidates[i] if c == remain: - ans.append(use + [c]) + ans.append(used + [c]) if c < remain: - find(i, use + [c], remain - c) + find(i, used + [c], remain - c) # 递归 if c > remain: return find(0, [], target) From 214d6f43120760fa3ff985c994d4ab2ecc1fa6bf Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 16:29:40 +0800 Subject: [PATCH 37/69] =?UTF-8?q?Update=200042-=E6=8E=A5=E9=9B=A8=E6=B0=B4?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2-\346\216\245\351\233\250\346\260\264.py" | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git "a/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" "b/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" index 8991e30..4903e05 100644 --- "a/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" +++ "b/0042.\346\216\245\351\233\250\346\260\264/0042-\346\216\245\351\233\250\346\260\264.py" @@ -40,3 +40,37 @@ def trap(self, height: List[int]) -> int: # 链接:https://leetcode-cn.com/problems/trapping-rain-water/solution/jie-yu-shui-by-leetcode-solution-tuvc/ # 来源:力扣(LeetCode) # 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + +# 方法三:双指针 +# 动态规划的做法中,需要维护两个数组 leftMax 和 rightMax,因此空间复杂度是 O(n)O(n)O(n)。是否可以将空间复杂度降到 O(1)O(1)O(1)? +# 注意到下标 i 处能接的雨水量由 leftMax[i] 和 rightMax[i] 中的最小值决定。由于数组 leftMax 是从左往右计算,数组 rightMax 是从右往左计算,因此可以使用双指针和两个变量代替两个数组。 +# 维护两个指针 left 和 right,以及两个变量 leftMax 和 rightMax,初始时 left=0,right=n−1,leftMax=0,rightMax=0。 +# 指针 left 只会向右移动,指针 right 只会向左移动,在移动指针的过程中维护两个变量 leftMax 和 rightMax 的值。 + +# 当两个指针没有相遇时,进行如下操作: +# 使用 height[left] 和 height[right] 的值更新 leftMax 和 rightMax 的值; +# 如果 height[left] int: + ans = 0 + left, right = 0, len(height) - 1 + leftMax = rightMax = 0 + + while left < right: + leftMax = max(leftMax, height[left]) + rightMax = max(rightMax, height[right]) + if height[left] < height[right]: + ans += leftMax - height[left] + left += 1 + else: + ans += rightMax - height[right] + right -= 1 + + return ans +# 作者:力扣官方题解 +# 链接:https://leetcode.cn/problems/trapping-rain-water/solutions/692342/jie-yu-shui-by-leetcode-solution-tuvc/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From f40ee2561dfad66f66921b11695e4e65d2e8cc67 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 16:35:35 +0800 Subject: [PATCH 38/69] =?UTF-8?q?Create=20=E6=91=98=E6=B0=B4=E6=9E=9C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\346\221\230\346\260\264\346\236\234.py" | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 "2106. \346\221\230\346\260\264\346\236\234/\346\221\230\346\260\264\346\236\234.py" diff --git "a/2106. \346\221\230\346\260\264\346\236\234/\346\221\230\346\260\264\346\236\234.py" "b/2106. \346\221\230\346\260\264\346\236\234/\346\221\230\346\260\264\346\236\234.py" new file mode 100644 index 0000000..793b2b4 --- /dev/null +++ "b/2106. \346\221\230\346\260\264\346\236\234/\346\221\230\346\260\264\346\236\234.py" @@ -0,0 +1,45 @@ +# 由于只能一步步地走,人移动的范围必然是一段连续的区间。 + +# 如果反复左右移动,会白白浪费移动次数,所以最优方案要么先向右再向左,要么先向左再向右(或者向一个方向走到底)。 + +# 设向左走最远可以到达 fruits[left][0]\textit{fruits}[\textit{left}][0]fruits[left][0],这可以用枚举或者二分查找得出,其中 left\textit{left}left 是最小的满足 + +# fruits[left][0]≥startPos−k +# 的下标。 + +# 假设位置不超过 startPos 的最近水果在 fruits[right][0],那么当 right 增加时,left 不可能减少,有单调性,因此可以用同向双指针(滑动窗口)解决。不了解的同学可以先看上面的视频讲解。 + +# 如何判断 left 是否需要增加呢? + +# 如果先向右再向左,那么移动距离为 + +# (fruits[right][0]−startPos)+(fruits[right][0]−fruits[left][0]) +# 如果先向左再向右,那么移动距离为 + +# (startPos−fruits[left][0])+(fruits[right][0]−fruits[left][0]) +# 如果上面两个式子均大于 k,就说明 fruits[left][0] 太远了,需要增加 left。 + +# 对于 right,它必须小于 n,且满足 + +# fruits[right][0]≤startPos+k +# 移动 left 和 right 的同时,维护窗口内的水果数量 s,同时用 s 更新答案的最大值。 + +class Solution: + def maxTotalFruits(self, fruits: List[List[int]], startPos: int, k: int) -> int: + left = bisect_left(fruits, [startPos - k]) # 向左最远能到 fruits[left][0] + right = bisect_left(fruits, [startPos + 1]) # startPos 右边最近水果(因为下面求的是左闭右开区间) + ans = s = sum(c for _, c in fruits[left:right]) # 从 fruits[left][0] 到 startPos 的水果数 + while right < len(fruits) and fruits[right][0] <= startPos + k: + s += fruits[right][1] # 枚举最右位置为 fruits[right][0] + while fruits[right][0] * 2 - fruits[left][0] - startPos > k and \ + fruits[right][0] - fruits[left][0] * 2 + startPos > k: + s -= fruits[left][1] # fruits[left][0] 无法到达 + left += 1 + ans = max(ans, s) # 更新答案最大值 + right += 1 # 继续枚举下一个最右位置 + return ans + +# 作者:灵茶山艾府 +# 链接:https://leetcode.cn/problems/maximum-fruits-harvested-after-at-most-k-steps/solutions/2254860/hua-dong-chuang-kou-jian-ji-xie-fa-pytho-1c2d/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 352926006130da9d898d661b12617164d37c2524 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 17:09:40 +0800 Subject: [PATCH 39/69] =?UTF-8?q?Update=200049-=E5=AD=97=E6=AF=8D=E5=BC=82?= =?UTF-8?q?=E4=BD=8D=E8=AF=8D=E5=88=86=E7=BB=84.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...15\350\257\215\345\210\206\347\273\204.py" | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git "a/0049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/0049-\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" "b/0049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/0049-\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" index 6998b4a..fb919d7 100644 --- "a/0049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/0049-\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" +++ "b/0049.\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204/0049-\345\255\227\346\257\215\345\274\202\344\275\215\350\257\215\345\210\206\347\273\204.py" @@ -1,18 +1,19 @@ -class Solution(object): - def groupAnagrams(self, strs): - """ - :type strs: List[str] - :rtype: List[List[str]] - """ - record = dict() - - for word in strs: - tmp = tuple(sorted(word)) - # print tmp - if tmp in record: - record[tmp].append(word) - else: - record[tmp] = [word] - return [val for key, val in record.items()] +# 主要是dict.get()函数的理解 dict.get(key, default=None) 1. key -- 字典中要查找的键。 +# 2. default -- 如果指定键的值不存在时,返回该默认值。 + +# 还有一点要注意:因为字典的键,必须是不可变类型,所以用tuple。 + +class Solution: + def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + dict = {} + for item in strs: + key = tuple(sorted(item)) + dict[key] = dict.get(key, []) + [item] + return list(dict.values()) + +# 作者:梦之痕 +# 链接:https://leetcode.cn/problems/group-anagrams/solutions/254945/python3-99-by-meng-zhi-hen-n/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 - \ No newline at end of file + From e5236eb3333d93f54dec32a6b7fe712297c203d0 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 17:22:37 +0800 Subject: [PATCH 40/69] =?UTF-8?q?Update=200064-=E6=9C=80=E5=B0=8F=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...17\350\267\257\345\276\204\345\222\214.py" | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git "a/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" "b/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" index 3a026a4..294889c 100644 --- "a/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" +++ "b/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" @@ -9,29 +9,21 @@ # 题目要求,只能向右或向下走,换句话说,当前单元格 (i,j)(i,j) 只能从左方单元格 (i-1,j)(i−1,j) 或上方单元格 (i,j-1)(i,j−1) 走到,因此只需要考虑矩阵左边界和上边界。 # 走到当前单元格 (i,j)(i,j) 的最小路径和 == “从左方单元格 (i-1,j)(i−1,j) 与 从上方单元格 (i,j-1)(i,j−1) 走来的 两个最小路径和中较小的 ” ++ 当前单元格值 grid[i][j]grid[i][j] 。具体分为以下 44 种情况: -# 当左边和上边都不是矩阵边界时: 即当i \not= 0i -#  -# ​ -# =0, j \not= 0j -#  -# ​ -# =0时,dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]dp[i][j]=min(dp[i−1][j],dp[i][j−1])+grid[i][j] ; -# 当只有左边是矩阵边界时: 只能从上面来,即当i = 0, j \not= 0i=0,j -#  -# ​ -# =0时, dp[i][j] = dp[i][j - 1] + grid[i][j]dp[i][j]=dp[i][j−1]+grid[i][j] ; -# 当只有上边是矩阵边界时: 只能从左面来,即当i \not= 0, j = 0i -#  -# ​ -# =0,j=0时, dp[i][j] = dp[i - 1][j] + grid[i][j]dp[i][j]=dp[i−1][j]+grid[i][j] ; -# 当左边和上边都是矩阵边界时: 即当i = 0, j = 0i=0,j=0时,其实就是起点, dp[i][j] = grid[i][j]dp[i][j]=grid[i][j]; +# 当左边和上边都不是矩阵边界时: 即当i not= =0, j not= 0时, +# dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; +# 当只有左边是矩阵边界时: 只能从上面来,即当i = 0, j \not= 0时, +# dp[i][j] = dp[i][j - 1] + grid[i][j]; +# 当只有上边是矩阵边界时: 只能从左面来,即当i not= 0, j = 0时, +# dp[i][j] = dp[i - 1][j] + grid[i][j]; +# 当左边和上边都是矩阵边界时: 即当i = 0, j = 0时,其实就是起点, dp[i][j] = grid[i][j]; # 初始状态: -# dpdp 初始化即可,不需要修改初始 00 值。 +# dp 初始化即可,不需要修改初始 0 值。 # 返回值: -# 返回 dpdp 矩阵右下角值,即走到终点的最小路径和。 -# 其实我们完全不需要建立 dpdp 矩阵浪费额外空间,直接遍历 grid[i][j]grid[i][j] 修改即可。这是因为:grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j] ;原 gridgrid 矩阵元素中被覆盖为 dpdp 元素后(都处于当前遍历点的左上方),不会再被使用到。 +# 返回 dp 矩阵右下角值,即走到终点的最小路径和。 +# 其实我们完全不需要建立 dp 矩阵浪费额外空间,直接遍历 grid[i][j] 修改即可。这是因为:grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j] ; +# 原 grid 矩阵元素中被覆盖为 dp 元素后(都处于当前遍历点的左上方),不会再被使用到。 # 复杂度分析: # 时间复杂度 O(M \times N)O(M×N) : 遍历整个 gridgrid 矩阵元素。 From 9a5ffacaf64d17fdfb643ea202f7184ed41661b6 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 17:23:07 +0800 Subject: [PATCH 41/69] =?UTF-8?q?Update=200064-=E6=9C=80=E5=B0=8F=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=92=8C.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...34\200\345\260\217\350\267\257\345\276\204\345\222\214.py" | 4 ++++ 1 file changed, 4 insertions(+) diff --git "a/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" "b/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" index 294889c..fecda1a 100644 --- "a/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" +++ "b/0064.\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214/0064-\346\234\200\345\260\217\350\267\257\345\276\204\345\222\214.py" @@ -11,11 +11,15 @@ # 走到当前单元格 (i,j)(i,j) 的最小路径和 == “从左方单元格 (i-1,j)(i−1,j) 与 从上方单元格 (i,j-1)(i,j−1) 走来的 两个最小路径和中较小的 ” ++ 当前单元格值 grid[i][j]grid[i][j] 。具体分为以下 44 种情况: # 当左边和上边都不是矩阵边界时: 即当i not= =0, j not= 0时, # dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; + # 当只有左边是矩阵边界时: 只能从上面来,即当i = 0, j \not= 0时, # dp[i][j] = dp[i][j - 1] + grid[i][j]; + # 当只有上边是矩阵边界时: 只能从左面来,即当i not= 0, j = 0时, # dp[i][j] = dp[i - 1][j] + grid[i][j]; + # 当左边和上边都是矩阵边界时: 即当i = 0, j = 0时,其实就是起点, dp[i][j] = grid[i][j]; + # 初始状态: # dp 初始化即可,不需要修改初始 0 值。 From 8d827bff09360e313d4c204106ba2990f3d14506 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 18:04:41 +0800 Subject: [PATCH 42/69] =?UTF-8?q?Update=200253-=E4=BC=9A=E8=AE=AE=E5=AE=A4?= =?UTF-8?q?II.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\344\274\232\350\256\256\345\256\244II.py" | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git "a/0253.\344\274\232\350\256\256\345\256\244II/0253-\344\274\232\350\256\256\345\256\244II.py" "b/0253.\344\274\232\350\256\256\345\256\244II/0253-\344\274\232\350\256\256\345\256\244II.py" index b66bc55..fc48c72 100644 --- "a/0253.\344\274\232\350\256\256\345\256\244II/0253-\344\274\232\350\256\256\345\256\244II.py" +++ "b/0253.\344\274\232\350\256\256\345\256\244II/0253-\344\274\232\350\256\256\345\256\244II.py" @@ -1,23 +1,33 @@ +# 给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei), +# 为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。 + +# 题目给出若干区间,问最多有几个区间发生重叠。这个问题非常适合适用差分数组来求解。 +# 具体来说,就是使用一个计数器cnt表示当前正在召开的会议,然后从小到大遍历所有的时间点。 +# 若当前时间点有会议召开,那么就将cnt加上1,反之,若当前时间有会议结束,那么就将cnt减去1。 +# 得到最新的cnt之后,则使用cnt来更新答案。 + +# 在这里需要特别注意的是,由于题目中的区间是左闭右开的,因此在计算cnt时如果碰到相同的时间点,则应该先处理结束的会议,再处理新召开的会议。 +# 例如两场会议,时间分别是[1, 3)和[3, 5),那么在3这个时间点应该先处理[1, 3)的结束,再处理[3, 5)的召开。 + class Solution(object): def minMeetingRooms(self, intervals): """ :type intervals: List[List[int]] :rtype: int """ - if not intervals: - return 0 - if not intervals[0]: - return 1 - intervals = sorted(intervals, key = lambda x: x[1]) - record = [0 for _ in range(intervals[-1][1] + 1)] + + res = cnt = 0 + time_points = [] + for x, y in intervals: + time_points.append([x, 1]) + time_points.append([y, 0]) - for interval in intervals: - # print record - begin, end = interval[0], interval[1] - record[begin] += 1 - record[end] -= 1 - - for i, x in enumerate(record): - if i > 0: - record[i] += record[i - 1] - return max(record) \ No newline at end of file + for t, p in sorted(time_points): + if p == 0: + cnt -= 1 + else: + cnt += 1 + + res = max(res, cnt) + + return res From 6b7c41ce1c937096cb6da8753eb3d6e893a72528 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 18:07:31 +0800 Subject: [PATCH 43/69] =?UTF-8?q?Update=200078-=E5=AD=90=E9=9B=86.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0078-\345\255\220\351\233\206.py" | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git "a/0078.\345\255\220\351\233\206/0078-\345\255\220\351\233\206.py" "b/0078.\345\255\220\351\233\206/0078-\345\255\220\351\233\206.py" index 6012ad0..95cd33b 100644 --- "a/0078.\345\255\220\351\233\206/0078-\345\255\220\351\233\206.py" +++ "b/0078.\345\255\220\351\233\206/0078-\345\255\220\351\233\206.py" @@ -1,14 +1,23 @@ -class Solution(object): - def subsets(self, nums): - """ - :type nums: List[int] - :rtype: List[List[int]] - """ +# 思路一、库函数 + + +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + res = [] + for i in range(len(nums)+1): + for tmp in itertools.combinations(nums, i): + res.append(tmp) + return res + +# 思路二、迭代 +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: res = [[]] - for num in nums: - tmp = res[:] - for item in res: - tmp.append(item + [num]) - res = tmp[:] - - return res \ No newline at end of file + for i in nums: + res = res + [[i] + num for num in res] + return res + +# 作者:powcai +# 链接:https://leetcode.cn/problems/subsets/solutions/6899/hui-su-suan-fa-by-powcai-5/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 6287226f98afde89f109418e2acf7bd232015b5c Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 19:46:21 +0800 Subject: [PATCH 44/69] =?UTF-8?q?Update=200079-=E5=8D=95=E8=AF=8D=E6=90=9C?= =?UTF-8?q?=E7=B4=A2.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...25\350\257\215\346\220\234\347\264\242.py" | 64 +++++++++---------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git "a/0079.\345\215\225\350\257\215\346\220\234\347\264\242/0079-\345\215\225\350\257\215\346\220\234\347\264\242.py" "b/0079.\345\215\225\350\257\215\346\220\234\347\264\242/0079-\345\215\225\350\257\215\346\220\234\347\264\242.py" index d3cdcde..98a034f 100644 --- "a/0079.\345\215\225\350\257\215\346\220\234\347\264\242/0079-\345\215\225\350\257\215\346\220\234\347\264\242.py" +++ "b/0079.\345\215\225\350\257\215\346\220\234\347\264\242/0079-\345\215\225\350\257\215\346\220\234\347\264\242.py" @@ -1,37 +1,31 @@ -class Solution(object): - def exist(self, board, word): - """ - :type board: List[List[str]] - :type word: str - :rtype: bool - """ - if not board or not board[0]: - return False +# 回溯算法 + dfs +class Solution: + def exist(self, board: List[List[str]], word: str) -> bool: + row = len(board) + col = len(board[0]) - m, n = len(board), len(board[0]) - dx = [1, -1, 0, 0] - dy = [0, 0, 1, -1] - self.res = False - def dfs(word_idx, x0, y0): - # print word_idx - if word_idx >= len(word): - self.res = True - return - if not self.res: - for k in range(len(dx)): - x1 = x0 + dx[k] - y1 = y0 + dy[k] + def core_function(i, j, k, visited): + #print(i,j, k,visited) + if k == len(word): + return True + for x, y in [(-1, 0), (1, 0), (0, 1), (0, -1)]: + tmp_i = x + i + tmp_j = y + j + if 0 <= tmp_i < row and 0 <= tmp_j < col and (tmp_i, tmp_j) not in visited \ + and board[tmp_i][tmp_j] == word[k]: # 如果位置合法,没有被访问过,词内容也正确 + visited.add((tmp_i, tmp_j)) + if core_function(tmp_i, tmp_j, k+1, visited): + return True + visited.remove((tmp_i, tmp_j)) # 回溯 + return False + + for i in range(row): + for j in range(col): + if board[i][j] == word[0] and core_function(i, j, 1,{(i, j)}) : + return True + return False - if 0 <= x1 < m and 0 <= y1 < n and board[x1][y1] == word[word_idx]: - temp = board[x1][y1] - board[x1][y1] = -1 - dfs(word_idx + 1, x1, y1) - board[x1][y1] = temp - for i in range(m): - for j in range(n): - if board[i][j] == word[0]: - temp = board[i][j] - board[i][j] = 0 - dfs(1, i, j) - board[i][j] = temp - return self.res \ No newline at end of file +作者:powcai +链接:https://leetcode.cn/problems/word-search/solutions/6907/hui-su-dfs-by-powcai/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From d66e64a4e30ab0321a69b5a4a0f22f4eae4ed185 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 20:15:31 +0800 Subject: [PATCH 45/69] =?UTF-8?q?Update=200084-=E6=9F=B1=E7=8A=B6=E5=9B=BE?= =?UTF-8?q?=E4=B8=AD=E6=9C=80=E5=A4=A7=E7=9A=84=E7=9F=A9=E5=BD=A2.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...47\347\232\204\347\237\251\345\275\242.py" | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git "a/0084.\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242/0084-\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242.py" "b/0084.\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242/0084-\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242.py" index 0a6ac26..4bf0a00 100644 --- "a/0084.\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242/0084-\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242.py" +++ "b/0084.\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242/0084-\346\237\261\347\212\266\345\233\276\344\270\255\346\234\200\345\244\247\347\232\204\347\237\251\345\275\242.py" @@ -1,6 +1,28 @@ +首先,要想找到第 i 位置最大面积是什么? +是以 i 为中心,向左找第一个小于 heights[i] 的位置 left_i;向右找第一个小于于 heights[i] 的位置 right_i, +即最大面积为 heights[i] * (right_i - left_i -1) +所以,我们的问题就变成如何找right_i 和 left_i? + +# 暴力解法,会超时 +class Solution: + def largestRectangleArea(self, heights: List[int]) -> int: + res = 0 + n = len(heights) + for i in range(n): + left_i = i + right_i = i + while left_i >= 0 and heights[left_i] >= heights[i]: + left_i -= 1 + while right_i < n and heights[right_i] >= heights[i]: + right_i += 1 + res = max(res, (right_i - left_i - 1) * heights[i]) + return res + +# 单调栈 class Solution: def largestRectangleArea(self, heights: List[int]) -> int: - heights = [0] + heights + [0] + heights = [0] + heights + [0] #如果遍历之后,栈不为空,那么还需要一步:即弹出栈中所有元素,分别计算最大面积。然而当加了两个0以后,在结束后,栈一定为空! + # 因为0入栈的时候,会把前面所有的数全部弹出,如果0最后一个入栈,所有的数都会弹出;头部加0便于处理当栈里只有一个有效元素要弹出的时候计算面积 res = 0 stack = [] for i in range(len(heights)): @@ -9,4 +31,4 @@ def largestRectangleArea(self, heights: List[int]) -> int: res = max(res, (i - stack[-1] - 1) * heights[top]) stack.append(i) - return res \ No newline at end of file + return res From 3f4c6c3a96e32a1c8287afef76dfd42e7ef264ee Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 20:24:20 +0800 Subject: [PATCH 46/69] Create 0085.py --- .../0085.py" | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 "0085 \346\234\200\345\244\247\347\237\251\345\275\242/0085.py" diff --git "a/0085 \346\234\200\345\244\247\347\237\251\345\275\242/0085.py" "b/0085 \346\234\200\345\244\247\347\237\251\345\275\242/0085.py" new file mode 100644 index 0000000..d62eb01 --- /dev/null +++ "b/0085 \346\234\200\345\244\247\347\237\251\345\275\242/0085.py" @@ -0,0 +1,41 @@ +参数定义 +m,n:矩阵行列数 +pre:长度为n+1,初始值为0的数组,记录每个位置上方(包含当前位置)连续1的个数,最后一个位置为0,便于单调栈处理 +stack:单调栈,存储元素的索引,且索引对应的元素单调递增 + +思路                                +前缀和思想求连续1的个数: +对于pre的计算,当前位置j为0,则pre[j]=0,当前位置为1,则需要加上上一层连续1的个数,即pre[j]+=1。 +如第二行(下标从0开始)pre[2]=[3,1,3,2,2,0],最后多一个0便于单调栈处理 +单调栈计算最大矩形: +初始化栈,存入下标-1,便于处理所有元素弹出栈后的情况 +当栈顶索引index对应的元素pre[index]大于当前索引为k的元素num时,将栈顶元素index弹出,因为栈中索引对应的值是单调递增的,所以此时栈顶元素stack[-1]到k-1之间的数均是不小于pre[index]的,此时以pre[index]为高的矩阵的长度为k-stack[-1]-1,面积S=pre[index]*(k-stack[-1]-1) +pre数组末尾添加0的目的,就是能将所有元素弹出栈,从而计算所有矩阵面积 +利用res记录最大矩阵面积 + +class Solution: + def maximalRectangle(self, matrix: List[List[str]]) -> int: + if not matrix:return 0 + m,n=len(matrix),len(matrix[0]) + # 记录当前位置上方连续“1”的个数 + pre=[0]*(n+1) + res=0 + for i in range(m): + for j in range(n): + # 前缀和 + pre[j]=pre[j]+1 if matrix[i][j]=="1" else 0 + + # 单调栈 + stack=[-1] + for k,num in enumerate(pre): + while stack and pre[stack[-1]]>num: + index=stack.pop() + res=max(res,pre[index]*(k-stack[-1]-1)) + stack.append(k) + + return res + +# 作者:追风少年 +# 链接:https://leetcode.cn/problems/maximal-rectangle/solutions/535898/python3-qian-zhui-he-dan-diao-zhan-ji-su-vkpp/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From b3bff83a3e3d9365f7b2f40f1fe2f9646ebf18a1 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 20:27:55 +0800 Subject: [PATCH 47/69] =?UTF-8?q?Update=200121-=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\344\275\263\346\227\266\346\234\272.py" | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git "a/0121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272/0121-\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" "b/0121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272/0121-\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" index 325ada7..0d47a37 100644 --- "a/0121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272/0121-\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" +++ "b/0121.\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272/0121-\344\271\260\345\215\226\350\202\241\347\245\250\347\232\204\346\234\200\344\275\263\346\227\266\346\234\272.py" @@ -1,12 +1,14 @@ -class Solution(object): - def maxProfit(self, prices): - """ - :type prices: List[int] - :rtype: int - """ - res = 0 - pre_min = prices[0] if prices else 0 +# 遍历一遍数组,计算每次 到当天为止 的最小股票价格和最大利润。 +class Solution: + def maxProfit(self, prices: List[int]) -> int: + minprice = float('inf') + maxprofit = 0 for price in prices: - res = max(res, price - pre_min) - pre_min = min(pre_min, price) - return res \ No newline at end of file + minprice = min(minprice, price) + maxprofit = max(maxprofit, price - minprice) + return maxprofit + +# 作者:腐烂的橘子 +# 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/solutions/139559/gu-piao-wen-ti-python3-c-by-z1m/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 4ae053efc4bd2ccd31b1a4cae7840608a017617c Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 20:30:42 +0800 Subject: [PATCH 48/69] =?UTF-8?q?Update=200128-=E6=9C=80=E9=95=BF=E8=BF=9E?= =?UTF-8?q?=E7=BB=AD=E5=BA=8F=E5=88=97.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...36\347\273\255\345\272\217\345\210\227.py" | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git "a/0128.\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227/0128-\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227.py" "b/0128.\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227/0128-\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227.py" index fe318e8..684e9c2 100644 --- "a/0128.\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227/0128-\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227.py" +++ "b/0128.\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227/0128-\346\234\200\351\225\277\350\277\236\347\273\255\345\272\217\345\210\227.py" @@ -1,21 +1,21 @@ -class Solution(object): - def longestConsecutive(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - record = dict() +class Solution: + def longestConsecutive(self, nums: List[int]) -> int: + lookup = {} res = 0 for num in nums: - if num not in record: - left = record.get(num - 1, 0) - right = record.get(num + 1, 0) - - length = right + left + 1 - - res = max(res, length) - - for i in [num - left, num, num + right]: - record[i] = length - - return res \ No newline at end of file + if num not in lookup: + # 判断左右是否可以连起来 + left = lookup[num - 1] if num - 1 in lookup else 0 + right = lookup[num + 1] if num + 1 in lookup else 0 + # 记录长度 + lookup[num] = left + right + 1 + # 把头尾都设置为最长长度 + lookup[num - left] = left + right + 1 + lookup[num + right] = left + right + 1 + res = max(res, left + right + 1) + return res + +# 作者:powcai +# 链接:https://leetcode.cn/problems/longest-consecutive-sequence/solutions/14152/ji-he-huo-zhe-ha-xi-by-powcai/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From afeb11db4d3c0ee2f73925d97287149605b86ed4 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Sat, 3 Jun 2023 20:43:10 +0800 Subject: [PATCH 49/69] =?UTF-8?q?Update=200139-=E5=8D=95=E8=AF=8D=E6=8B=86?= =?UTF-8?q?=E5=88=86.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...25\350\257\215\346\213\206\345\210\206.py" | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git "a/0139.\345\215\225\350\257\215\346\213\206\345\210\206/0139-\345\215\225\350\257\215\346\213\206\345\210\206.py" "b/0139.\345\215\225\350\257\215\346\213\206\345\210\206/0139-\345\215\225\350\257\215\346\213\206\345\210\206.py" index 9ada5e0..818d5ca 100644 --- "a/0139.\345\215\225\350\257\215\346\213\206\345\210\206/0139-\345\215\225\350\257\215\346\213\206\345\210\206.py" +++ "b/0139.\345\215\225\350\257\215\346\213\206\345\210\206/0139-\345\215\225\350\257\215\346\213\206\345\210\206.py" @@ -1,13 +1,26 @@ class Solution: - def wordBreak(self, s: str, wordDict: List[str]) -> bool: - from collections import deque - wordDict = set(wordDict) - record = [0] +方法一:动态规划 - for i in range(len(s) + 1): - for j in record: - if s[j:i] in wordDict: - record.append(i) - break - # print (record) - return record[-1] == len(s) \ No newline at end of file +1. 初始化 dp=[False,⋯,False],长度为 n+1。n 为字符串长度。dp[i] 表示 s 的前 i 位是否可以用 wordDictword 中的单词表示。 +2. 初始化 dp[0]=True,空字符可以被表示。 +3.遍历字符串的所有子串,遍历开始索引 i,遍历区间 [0,n): + 遍历结束索引 j,遍历区间 [i+1,n+1): + 若 dp[i]=True 且 s[i,⋯,j) 在 wordlist 中:dp[j]=True。 + 解释:dp[i]=True 说明 s 的前 i 位可以用 wordDict 表示,则 s[i,⋯,j) 出现在 wordDict 中,说明 s 的前 j 位可以表示。 +4. 返回 dp[n] + +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + n=len(s) + dp=[False]*(n+1) + dp[0]=True + for i in range(n): + for j in range(i+1,n+1): + if(dp[i] and (s[i:j] in wordDict)): + dp[j]=True + return dp[-1] + +# 作者:吴彦祖 +# 链接:https://leetcode.cn/problems/word-break/solutions/50986/dong-tai-gui-hua-ji-yi-hua-hui-su-zhu-xing-jie-shi/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 6c77d0ab2a6055d1b2a25d98c2f4ab6fc1ef90dd Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 10:43:32 +0800 Subject: [PATCH 50/69] =?UTF-8?q?Update=200148-=E6=8E=92=E5=BA=8F=E9=93=BE?= =?UTF-8?q?=E8=A1=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...22\345\272\217\351\223\276\350\241\250.py" | 57 +++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git "a/0148.\346\216\222\345\272\217\351\223\276\350\241\250/0148-\346\216\222\345\272\217\351\223\276\350\241\250.py" "b/0148.\346\216\222\345\272\217\351\223\276\350\241\250/0148-\346\216\222\345\272\217\351\223\276\350\241\250.py" index 8d99052..86d82ed 100644 --- "a/0148.\346\216\222\345\272\217\351\223\276\350\241\250/0148-\346\216\222\345\272\217\351\223\276\350\241\250.py" +++ "b/0148.\346\216\222\345\272\217\351\223\276\350\241\250/0148-\346\216\222\345\272\217\351\223\276\350\241\250.py" @@ -10,9 +10,9 @@ def sortList(self, head): :type head: ListNode :rtype: ListNode """ - #1. һΪ - #2. - #3. ϶Ϊһ + #1. 一分为二 + #2. 各自排序 + #3. 合二为一 if not head or not head.next: return head @@ -48,4 +48,53 @@ def merge(self, l1, l2): tmp = ListNode(l2.val) tmp.next = self.merge(l1, l2.next) - return tmp \ No newline at end of file + return tmp + +# 应该和上面的思路相同 + #1. 一分为二 + #2. 各自排序 + #3. 合二为一 +class Solution: + def sortList(self, head: ListNode) -> ListNode: + if not head or not head.next: + return head + slow = head + fast = head + # 用快慢指针分成两部分 + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + # 找到左右部分, 把左部分最后置空 + mid = slow.next + slow.next = None + # 递归下去 + left = self.sortList(head) + right = self.sortList(mid) + # 合并 + return self.merge(left, right) + + def merge(self, left, right): + dummy = ListNode(0) + p = dummy + l = left + r = right + + while l and r: + if l.val < r.val: + p.next = l + l = l.next + p = p.next + else: + p.next = r + r = r.next + p = p.next + if l: + p.next = l + if r: + p.next = r + return dummy.next + +作者:Junhao +链接:https://leetcode.cn/problems/sort-list/solutions/215640/lc148-jian-ji-pythongui-bing-shi-xian-by-jhhuang/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 979228fa40a4c51f05a75a135797a469eac74456 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 10:45:18 +0800 Subject: [PATCH 51/69] =?UTF-8?q?Update=200152-=E4=B9=98=E7=A7=AF=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E5=AD=90=E5=BA=8F=E5=88=97.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...47\345\255\220\345\272\217\345\210\227.py" | 66 +++++++++++++------ 1 file changed, 47 insertions(+), 19 deletions(-) diff --git "a/0152.\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227/0152-\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227.py" "b/0152.\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227/0152-\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227.py" index 8c92d31..7d8f1d2 100644 --- "a/0152.\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227/0152-\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227.py" +++ "b/0152.\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227/0152-\344\271\230\347\247\257\346\234\200\345\244\247\345\255\220\345\272\217\345\210\227.py" @@ -1,19 +1,47 @@ -class Solution(object): - def maxProduct(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - #dp[i] = max(nums[i], nums[i] * dp[i - 1]) - - dp = [0 for i in nums] - dpmin = [0 for i in nums] - - dp[0], dpmin[0] = nums[0], nums[0] - for i, num in enumerate(nums): - if i > 0: - dp[i] = max(num, max(dp[i - 1] * num, dpmin[i - 1] * num)) - dpmin[i] = min(num, min(dp[i - 1] * num, dpmin[i - 1] * num)) - - # print dp - return max(dp) \ No newline at end of file +思路一:类似滑动窗口的感觉 + +product(i, j) = product(0, j) / product(0, i) 从数组 i 到 j 的累乘等于 从数组开头到 j 的累乘除以从数组开头到 i 的累乘(这里先忽略 0 的情况),要考虑三种情况 + +累乘的乘积等于 0,就要重新开始 + +累乘的乘积小于 0,要找到前面最大的负数,这样才能保住从 i 到 j 最大 + +累乘的乘积大于 0,要找到前面最小的正数,同理! + +class Solution: + def maxProduct(self, nums: List[int]) -> int: + if not nums: return + # 目前的累乘 + cur_pro = 1 + # 前面最小的正数 + min_pos = 1 + # 前面最大的负数 + max_neg = float("-inf") + # 结果 + res = float("-inf") + for num in nums: + cur_pro *= num + # 考虑三种情况 + # 大于0 + if cur_pro > 0: + res = max(res, cur_pro // min_pos) + min_pos = min(min_pos, cur_pro) + # 小于0 + elif cur_pro < 0: + if max_neg != float("-inf"): + res = max(res, cur_pro // max_neg) + else: + res = max(res, num) + max_neg = max(max_neg, cur_pro) + # 等于0 + else: + cur_pro = 1 + min_pos = 1 + max_neg = float("-inf") + res = max(res, num) + return res + +作者:powcai +链接:https://leetcode.cn/problems/maximum-product-subarray/solutions/17709/duo-chong-si-lu-qiu-jie-by-powcai-3/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 1eca0405c679022d94145a1427515edf96bc5887 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 10:53:23 +0800 Subject: [PATCH 52/69] =?UTF-8?q?Update=200155-=E6=9C=80=E5=B0=8F=E6=A0=88?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5-\346\234\200\345\260\217\346\240\210.py" | 52 ++++++------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git "a/0155.\346\234\200\345\260\217\346\240\210/0155-\346\234\200\345\260\217\346\240\210.py" "b/0155.\346\234\200\345\260\217\346\240\210/0155-\346\234\200\345\260\217\346\240\210.py" index 0b9c216..e399268 100644 --- "a/0155.\346\234\200\345\260\217\346\240\210/0155-\346\234\200\345\260\217\346\240\210.py" +++ "b/0155.\346\234\200\345\260\217\346\240\210/0155-\346\234\200\345\260\217\346\240\210.py" @@ -1,47 +1,29 @@ -class MinStack(object): - +class MinStack: + def __init__(self): - """ - initialize your data structure here. - """ - self.s = [] - self.min_s = [] + self.data = [(None, float('inf'))] - def push(self, x): - """ - :type x: int - :rtype: None - """ - self.s.append(x) - if self.min_s: - self.min_s.append(min(x, self.min_s[-1])) - else: - self.min_s.append(x) + def push(self, x: 'int') -> 'None': + self.data.append((x, min(x, self.data[-1][1]))) - def pop(self): - """ - :rtype: None - """ - self.min_s.pop() - self.s.pop() + def pop(self) -> 'None': + if len(self.data) > 1: self.data.pop() + def top(self) -> 'int': + return self.data[-1][0] - def top(self): - """ - :rtype: int - """ - return self.s[-1] + def getMin(self) -> 'int': + return self.data[-1][1] - def getMin(self): - """ - :rtype: int - """ - return self.min_s[-1] - # Your MinStack object will be instantiated and called as such: # obj = MinStack() # obj.push(x) # obj.pop() # param_3 = obj.top() -# param_4 = obj.getMin() \ No newline at end of file +# param_4 = obj.getMin() + +# 作者: +# 链接:https://leetcode.cn/problems/min-stack/solutions/4114/python-mei-ge-yi-xing-by-knifezhu/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 9718a9544377544a839ff624ad36f74c75f4327e Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 11:03:36 +0800 Subject: [PATCH 53/69] =?UTF-8?q?Update=200160-=E7=9B=B8=E4=BA=A4=E9=93=BE?= =?UTF-8?q?=E8=A1=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...70\344\272\244\351\223\276\350\241\250.py" | 64 ++++++++----------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git "a/0160.\347\233\270\344\272\244\351\223\276\350\241\250/0160-\347\233\270\344\272\244\351\223\276\350\241\250.py" "b/0160.\347\233\270\344\272\244\351\223\276\350\241\250/0160-\347\233\270\344\272\244\351\223\276\350\241\250.py" index c3b380b..6534a80 100644 --- "a/0160.\347\233\270\344\272\244\351\223\276\350\241\250/0160-\347\233\270\344\272\244\351\223\276\350\241\250.py" +++ "b/0160.\347\233\270\344\272\244\351\223\276\350\241\250/0160-\347\233\270\344\272\244\351\223\276\350\241\250.py" @@ -1,37 +1,29 @@ -# Definition for singly-linked list. -# class ListNode(object): -# def __init__(self, x): -# self.val = x -# self.next = None +# 设「第一个公共节点」为 node ,「链表 headA」的节点数量为 a ,「链表 headB」的节点数量为 b ,「两链表的公共尾部」的节点数量为 c ,则有: +# 头节点 headA 到 node 前,共有 a−c 个节点; +# 头节点 headB 到 node 前,共有 b−c 个节点; -class Solution(object): - def getIntersectionNode(self, headA, headB): - """ - :type head1, head1: ListNode - :rtype: ListNode - """ - pa, pb = headA, headB - la, lb = 0, 0 - while pa: - la += 1 - pa = pa.next - - while pb: - lb += 1 - pb = pb.next - - if la < lb: - la, lb, headA, headB = lb, la, headB, headA - - n = la - lb - pa, pb = headA, headB - while n: - pa = pa.next - n -= 1 - - while pa: - if pa == pb: - return pa - pa = pa.next - pb = pb.next - return None \ No newline at end of file + +# 考虑构建两个节点指针 A , B 分别指向两链表头节点 headA , headB ,做如下操作: + +# 指针 A 先遍历完链表 headA ,再开始遍历链表 headB ,当走到 node 时,共走步数为: +# a+(b−c) + +# 指针 B 先遍历完链表 headB ,再开始遍历链表 headA ,当走到 node 时,共走步数为: +# b+(a−c) +# 因为 a+(b−c) = b+(a−c),即此时指针 A , B 重合,并有两种情况: +# 若两链表 有 公共尾部 (即 c>0) :指针 A , B 同时指向「第一个公共节点」node 。 +# 若两链表 无 公共尾部 (即 c=0) :指针 A , B 同时指向 null。 +# 因此返回 A 即可。 + +class Solution: + def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: + A, B = headA, headB + while A != B: # 就算没有公共节点,A , B 同时指向 null也不会导致死循环 + A = A.next if A else headB + B = B.next if B else headA + return A + +# 作者:Krahets +# 链接:https://leetcode.cn/problems/intersection-of-two-linked-lists/solutions/12624/intersection-of-two-linked-lists-shuang-zhi-zhen-l/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From c7e6bd64785aaba872f86953abe07426f5d9d099 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 11:08:26 +0800 Subject: [PATCH 54/69] =?UTF-8?q?Update=200169-=E5=A4=9A=E6=95=B0=E5=85=83?= =?UTF-8?q?=E7=B4=A0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0169-\345\244\232\346\225\260\345\205\203\347\264\240.py" | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git "a/0169.\345\244\232\346\225\260\345\205\203\347\264\240/0169-\345\244\232\346\225\260\345\205\203\347\264\240.py" "b/0169.\345\244\232\346\225\260\345\205\203\347\264\240/0169-\345\244\232\346\225\260\345\205\203\347\264\240.py" index 858b7a2..5fd69f4 100644 --- "a/0169.\345\244\232\346\225\260\345\205\203\347\264\240/0169-\345\244\232\346\225\260\345\205\203\347\264\240.py" +++ "b/0169.\345\244\232\346\225\260\345\205\203\347\264\240/0169-\345\244\232\346\225\260\345\205\203\347\264\240.py" @@ -1,3 +1,6 @@ +摩尔投票法(Boyer–Moore majority vote algorithm), +也被称作「多数投票法」,算法解决的问题是:如何在任意多的候选人中(选票无序),选出获得票数最多的那个。要求众数过半 + class Solution(object): def majorityElement(self, nums): """ @@ -16,4 +19,4 @@ def majorityElement(self, nums): if vote_cnt == 0: vote = num vote_cnt = 1 - return vote \ No newline at end of file + return vote From 6c90264bb6404d9544aa59b1f90a3f3096731450 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 11:12:09 +0800 Subject: [PATCH 55/69] =?UTF-8?q?Update=200198-=E6=89=93=E5=AE=B6=E5=8A=AB?= =?UTF-8?q?=E8=88=8D.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...23\345\256\266\345\212\253\350\210\215.py" | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git "a/0198.\346\211\223\345\256\266\345\212\253\350\210\215/0198-\346\211\223\345\256\266\345\212\253\350\210\215.py" "b/0198.\346\211\223\345\256\266\345\212\253\350\210\215/0198-\346\211\223\345\256\266\345\212\253\350\210\215.py" index 3d94e44..c631ccd 100644 --- "a/0198.\346\211\223\345\256\266\345\212\253\350\210\215/0198-\346\211\223\345\256\266\345\212\253\350\210\215.py" +++ "b/0198.\346\211\223\345\256\266\345\212\253\350\210\215/0198-\346\211\223\345\256\266\345\212\253\350\210\215.py" @@ -1,14 +1,46 @@ -class Solution(object): - def rob(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - if len(nums) == 0: - return 0 - if len(nums) <= 2: - return max(nums) - nums[1] = max(nums[0], nums[1]) - for i in range(2, len(nums)): - nums[i] = max(nums[i - 2] + nums[i], nums[i - 1]) - return max(nums) if nums else 0 \ No newline at end of file +状态定义: +设动态规划列表 dpdpdp ,dp[i]dp[i]dp[i] 代表前 iii 个房子在满足条件下的能偷窃到的最高金额。 + +转移方程: +设: 有 nnn 个房子,前 nnn 间能偷窃到的最高金额是 dp[n]dp[n]dp[n] ,前 n−1n-1n−1 间能偷窃到的最高金额是 dp[n−1]dp[n-1]dp[n−1] ,此时向这些房子后加一间房,此房间价值为 numnumnum ; +加一间房间后: 由于不能抢相邻的房子,意味着抢第 n+1n+1n+1 间就不能抢第 nnn 间;那么前 n+1n+1n+1 间房能偷取到的最高金额 dp[n+1]dp[n+1]dp[n+1] 一定是以下两种情况的 较大值 : + +不抢第 n+1n+1n+1 个房间,因此等于前 nnn 个房子的最高金额,即 dp[n+1]=dp[n]dp[n+1] = dp[n]dp[n+1]=dp[n] ; +抢第 n+1n+1n+1 个房间,此时不能抢第 nnn 个房间;因此等于前 n−1n-1n−1 个房子的最高金额加上当前房间价值,即 dp[n+1]=dp[n−1]+numdp[n+1] = dp[n-1] + numdp[n+1]=dp[n−1]+num ; +细心的我们发现: 难道在前 nnn 间的最高金额 dp[n]dp[n]dp[n] 情况下,第 nnn 间一定被偷了吗?假设没有被偷,那 n+1n+1n+1 间的最大值应该也可能是 dp[n+1]=dp[n]+numdp[n+1] = dp[n] + numdp[n+1]=dp[n]+num 吧?其实这种假设的情况可以被省略,这是因为: + +假设第 nnn 间没有被偷,那么此时 dp[n]=dp[n−1]dp[n] = dp[n-1]dp[n]=dp[n−1] ,此时 dp[n+1]=dp[n]+num=dp[n−1]+numdp[n+1] = dp[n] + num = dp[n-1] + numdp[n+1]=dp[n]+num=dp[n−1]+num ,即两种情况可以 合并为一种情况 考虑; +假设第 nnn 间被偷,那么此时 dp[n+1]=dp[n]+numdp[n+1] = dp[n] + numdp[n+1]=dp[n]+num 不可取 ,因为偷了第 nnn 间就不能偷第 n+1n+1n+1 间。 +最终的转移方程: +dp[n+1] = max(dp[n],dp[n-1]+num) + +初始状态: + +前 000 间房子的最大偷窃价值为 000 ,即 dp[0]=0dp[0] = 0dp[0]=0 。 +返回值: + +返回 dpdpdp 列表最后一个元素值,即所有房间的最大偷窃价值。 +简化空间复杂度: + +我们发现 dp[n]dp[n]dp[n] 只与 dp[n−1]dp[n-1]dp[n−1] 和 dp[n−2]dp[n-2]dp[n−2] 有关系,因此我们可以设两个变量 cur和 pre 交替记录,将空间复杂度降到 O(1)O(1)O(1) 。 + +# 简化版 +class Solution: + def rob(self, nums: List[int]) -> int: + cur, pre = 0, 0 + for num in nums: + cur, pre = max(pre + num, cur), cur + return cur +# 标准版 +class Solution: + def rob(self, nums) -> int: + n = len(nums) + dp = [0]*(n+1) + dp[1] = nums[0] + for i in range(2,n+1): + dp[i] = max(dp[i-1],dp[i-2]+nums[i-1]) + return dp[-1] +# 作者:Krahets +# 链接:https://leetcode.cn/problems/house-robber/solutions/28242/da-jia-jie-she-dong-tai-gui-hua-jie-gou-hua-si-lu-/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From b24ba5acd1271924dfa18723d892177b0d898b73 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 11:15:10 +0800 Subject: [PATCH 56/69] =?UTF-8?q?Update=200200-=E5=B2=9B=E5=B1=BF=E6=95=B0?= =?UTF-8?q?=E9=87=8F.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...33\345\261\277\346\225\260\351\207\217.py" | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git "a/0200.\345\262\233\345\261\277\346\225\260\351\207\217/0200-\345\262\233\345\261\277\346\225\260\351\207\217.py" "b/0200.\345\262\233\345\261\277\346\225\260\351\207\217/0200-\345\262\233\345\261\277\346\225\260\351\207\217.py" index fc2adf0..34b46e5 100644 --- "a/0200.\345\262\233\345\261\277\346\225\260\351\207\217/0200-\345\262\233\345\261\277\346\225\260\351\207\217.py" +++ "b/0200.\345\262\233\345\261\277\346\225\260\351\207\217/0200-\345\262\233\345\261\277\346\225\260\351\207\217.py" @@ -1,31 +1,27 @@ +核心思想:BFS,如果发现一个陆地,便对其进行 BFS,并将可由 BFS 访问到的点都置为已经访问状态,从而代表同属一个岛屿,详解见注释。 + class Solution: def numIslands(self, grid: List[List[str]]) -> int: - from collections import deque - if not grid or not grid[0]: - return 0 - - m, n = len(grid), len(grid[0]) - - dx = [1, -1, 0, 0] - dy = [0, 0, 1, -1] - - res = 0 - for i in range(m): - for j in range(n): - if grid[i][j] == "1": - grid[i][j] = "0" - res += 1 - - queue = deque([(i, j)]) - - while queue: - x0, y0 = queue.popleft() - for k in range(4): - x = x0 + dx[k] - y = y0 + dy[k] - - if 0 <= x < m and 0 <= y < n and grid[x][y] == "1": - grid[x][y] = "0" - queue.append((x, y)) + count = 0 + for row in range(len(grid)): + for col in range(len(grid[0])): + if grid[row][col] == '1': # 发现陆地 + count += 1 # 结果加1 + grid[row][col] = '0' # 将其转为 ‘0’ 代表已经访问过 + # 对发现的陆地进行扩张即执行 BFS,将与其相邻的陆地都标记为已访问 + # 下面还是经典的 BFS 模板 + land_positions = collections.deque() + land_positions.append([row, col]) + while len(land_positions) > 0: + x, y = land_positions.popleft() + for new_x, new_y in [[x, y + 1], [x, y - 1], [x + 1, y], [x - 1, y]]: # 进行四个方向的扩张 + # 判断有效性 + if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]) and grid[new_x][new_y] == '1': + grid[new_x][new_y] = '0' # 因为可由 BFS 访问到,代表同属一块岛,将其置 ‘0’ 代表已访问过 + land_positions.append([new_x, new_y]) + return count - return res \ No newline at end of file +作者:莲子熊猫 +链接:https://leetcode.cn/problems/number-of-islands/solutions/210855/xiong-mao-shua-ti-python3-yi-jiu-shi-bfsmo-ban-ti-/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 44d1a2faa2e40aa57c61753840878823f4e720f2 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 11:17:48 +0800 Subject: [PATCH 57/69] =?UTF-8?q?Update=200206-=E5=8F=8D=E8=BD=AC=E9=93=BE?= =?UTF-8?q?=E8=A1=A8.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...15\350\275\254\351\223\276\350\241\250.py" | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git "a/0206.\345\217\215\350\275\254\351\223\276\350\241\250/0206-\345\217\215\350\275\254\351\223\276\350\241\250.py" "b/0206.\345\217\215\350\275\254\351\223\276\350\241\250/0206-\345\217\215\350\275\254\351\223\276\350\241\250.py" index ace8b9e..391bb0a 100644 --- "a/0206.\345\217\215\350\275\254\351\223\276\350\241\250/0206-\345\217\215\350\275\254\351\223\276\350\241\250.py" +++ "b/0206.\345\217\215\350\275\254\351\223\276\350\241\250/0206-\345\217\215\350\275\254\351\223\276\350\241\250.py" @@ -1,23 +1,32 @@ +首先 pre 指针指向 Null,cur 指针指向 head; + +当 cur != Null,执行循环。 + 先将 cur.next 保存在 temp 中防止链表丢失:temp = cur.next + 接着把 cur.next 指向前驱节点 pre:cur.next = pre + 然后将 pre 往后移一位也就是移到当前 cur 的位置:pre = cur + 最后把 cur 也往后移一位也就是 temp 的位置:cur = temp + +当 cur == Null,结束循环,返回 pre。 + # Definition for singly-linked list. -# class ListNode(object): +# class ListNode: # def __init__(self, x): # self.val = x # self.next = None -class Solution(object): - def reverseList(self, head): - """ - :type head: ListNode - :rtype: ListNode - """ - if not head or not head.next: - return head - pre, cur = None, head - while cur: - tmp = cur.next #β - cur.next = pre #תֲ - pre = cur #pre - cur = tmp #cur +class Solution: + def reverseList(self, head: ListNode) -> ListNode: + pre = None + cur = head + while cur: + temp = cur.next # 先把原来cur.next位置存起来 + cur.next = pre + pre = cur + cur = temp return pre - \ No newline at end of file +# 作者:憨憨阿狗 +# 链接:https://leetcode.cn/problems/reverse-linked-list/solutions/305898/tu-jie-liu-cheng-python3die-dai-xiang-jie-by-han-h/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + From e46da2c677f8e076a35030f2c84da21a8c2eab75 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 11:28:11 +0800 Subject: [PATCH 58/69] =?UTF-8?q?Update=200207-=E8=AF=BE=E7=A8=8B=E8=A1=A8?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...7-\350\257\276\347\250\213\350\241\250.py" | 82 +++++++++++++------ 1 file changed, 59 insertions(+), 23 deletions(-) diff --git "a/0207.\350\257\276\347\250\213\350\241\250/0207-\350\257\276\347\250\213\350\241\250.py" "b/0207.\350\257\276\347\250\213\350\241\250/0207-\350\257\276\347\250\213\350\241\250.py" index 23b832c..3c8f281 100644 --- "a/0207.\350\257\276\347\250\213\350\241\250/0207-\350\257\276\347\250\213\350\241\250.py" +++ "b/0207.\350\257\276\347\250\213\350\241\250/0207-\350\257\276\347\250\213\350\241\250.py" @@ -1,29 +1,65 @@ +这道题 就是找图中是否有环。 + +思路一:深度优先遍历 +时间复杂度:O(N+E) N 为顶点个数,E为边的个数 + +思路二:广度优先遍历 +通过顶点的入度的个数,每次消除入度为0顶点,看是否每一个节点都能被消除 + +时间复杂度 : O(N+E) N为顶点个数,E为边的个数 + +DFS class Solution: def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: - # 1. find all node/course with indegree 0, let them enter a queue - from collections import defaultdict, deque - indegree = defaultdict(int) - children = defaultdict(set) - all_courses = set() - for cur, pre in prerequisites: - indegree[cur] += 1 - children[pre].add(cur) - all_courses.add(cur) - all_courses.add(pre) + from collections import defaultdict + graph = defaultdict(list) + # 记录 + visited = set() + # 建图 + for x, y in prerequisites: + graph[y].append(x) - queue = deque([]) - for course in all_courses: - if indegree[course] == 0: - queue.append(course) - # 2. BFS, let course with indegree 0 leave a queue, and let its children with indegree 0 into the queue - studied_course = 0 + # 深度遍历 + def dfs(i, being_visited): + if i in being_visited: return False + if i in visited: return True + visited.add(i) + being_visited.add(i) + for j in graph[i]: + if not dfs(j, being_visited): return False + being_visited.remove(i) + return True + # 检测每门功课起始是否存在环 + for i in range(numCourses): + # 已经访问过 + if i in visited: continue + if not dfs(i, set()): return False + return True + +BFS +class Solution: + def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: + from collections import defaultdict, deque + graph = defaultdict(list) + degree = [0] * numCourses + # 建图 + for x, y in prerequisites: + graph[y].append(x) + degree[x] += 1 + queue = deque([i for i in range(numCourses) if degree[i] == 0]) + #print(queue) + cnt = 0 while queue: - cur = queue.popleft() + i = queue.pop() + cnt += 1 + for j in graph[i]: + degree[j] -= 1 + if degree[j] == 0: + queue.appendleft(j) + return cnt == numCourses - studied_course += 1 - for child in children[cur]: - indegree[child] -= 1 - if indegree[child] == 0: - queue.append(child) - return studied_course == len(all_courses) \ No newline at end of file +作者:powcai +链接:https://leetcode.cn/problems/course-schedule/solutions/21166/dfs-bfs-by-powcai/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 68f9661060d1ae12bee1cd7af2db8d9aeb121e8f Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 15:56:20 +0800 Subject: [PATCH 59/69] =?UTF-8?q?Update=200215-=E6=95=B0=E7=BB=84=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E7=AC=ACK=E4=B8=AA=E6=9C=80=E5=A4=A7=E5=85=83?= =?UTF-8?q?=E7=B4=A0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\345\244\247\345\205\203\347\264\240.py" | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git "a/0215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/0215-\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" "b/0215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/0215-\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" index 6c62036..5d5b4eb 100644 --- "a/0215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/0215-\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" +++ "b/0215.\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240/0215-\346\225\260\347\273\204\344\270\255\347\232\204\347\254\254K\344\270\252\346\234\200\345\244\247\345\205\203\347\264\240.py" @@ -1,3 +1,35 @@ +# 库函数 +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + return sorted(nums, reverse = True)[k - 1] + +# 手写快速排序 +class Solution: + def findKthLargest(self, nums: List[int], k: int) -> int: + def partition(left, right): + pivot = nums[left] + l = left + 1 + r = right + while l <= r: + if nums[l] < pivot and nums[r] > pivot: + nums[l], nums[r] = nums[r], nums[l] + if nums[l] >= pivot: + l += 1 + if nums[r] <= pivot: + r -= 1 + nums[r], nums[left] = nums[left], nums[r] + return r + left = 0 + right = len(nums) - 1 + while 1: + idx = partition(left, right) + if idx == k - 1: + return nums[idx] + if idx < k - 1: + left = idx + 1 + if idx > k - 1: + right = idx - 1 + class Solution(object): def findKthLargest(self, nums, k): """ @@ -10,9 +42,9 @@ def findKthLargest(self, nums, k): pos = self.partition(nums, left, right) if pos == target: return nums[pos] - elif pos > k: #Ҫ + elif pos > k: #要往左找 right = pos - 1 - elif pos < k: #Ҫ + elif pos < k: #要往右找 left = pos + 1 def partition(self, nums, left, right): @@ -27,4 +59,4 @@ def partition(self, nums, left, right): index += 1 nums[i], nums[index] = nums[index], nums[i] nums[left], nums[index] = nums[index], nums[left] - return index #ʱindexֵnums[index] Ҳֵnums[index]С \ No newline at end of file + return index #此时所有index左侧的值都比nums[index]大, 所有右侧的值都比nums[index]小 From 2b41ad267f1adc80614eaaf4673b90a4bc1819e9 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 17:15:28 +0800 Subject: [PATCH 60/69] =?UTF-8?q?Update=200239-=E6=BB=91=E5=8A=A8=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E6=9C=80=E5=A4=A7=E5=80=BC.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...43\346\234\200\345\244\247\345\200\274.py" | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git "a/0239.\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274/0239-\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" "b/0239.\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274/0239-\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" index 699c8d5..916cfc1 100644 --- "a/0239.\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274/0239-\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" +++ "b/0239.\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274/0239-\346\273\221\345\212\250\347\252\227\345\217\243\346\234\200\345\244\247\345\200\274.py" @@ -1,3 +1,33 @@ +1.利用双端队列记录当前滑动窗口的元素索引 +2.队列最左侧元素记录滑动窗口中最大元素的索引 +3.遍历数组: + 如果队列最左侧索引已不在滑动窗口范围内,弹出队列最左侧索引 + 通过循环确保队列的最左侧索引所对应元素值最大 + 新元素入队 + 从第一个滑动窗口的末尾索引开始将最大值存储到结果res中 + +class Solution: + def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: + res = [] +# queue = collections.deque() #如果不用deque,用list也行 + queue=[] + for i, num in enumerate(nums): + if queue and queue[0] == i - k: +# queue.popleft() + queue.pop(0) + while queue and nums[queue[-1]] < num: #比 nums[i] 小的都不要,因为只要窗口的最大值 + queue.pop() + queue.append(i) + if i >= k - 1: + res.append(nums[queue[0]]) + return res + +作者:郁郁雨 +链接:https://leetcode.cn/problems/sliding-window-maximum/solutions/626777/239-hua-dong-chuang-kou-zui-da-zhi-li-yo-2jqr/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + +#和上面相同,变量名称不同 class Solution(object): def maxSlidingWindow(self, nums, k): """ @@ -11,13 +41,13 @@ def maxSlidingWindow(self, nums, k): window = [] res = [] for i in range(len(nums)): - if window and window[0] <= i - k: #ǰwindowͷӦñ + if window and window[0] <= i - k: #当前window头应该被弹出 window.pop(0) - while window and nums[window[-1]] < nums[i]: # nums[i] СĶҪΪֻҪڵֵ + while window and nums[window[-1]] < nums[i]: #比 nums[i] 小的都不要,因为只要窗口的最大值 window.pop() window.append(i) if i >= k - 1: res.append(nums[window[0]]) - return res \ No newline at end of file + return res From b02448c49513a22f15b08ad092ff84b2f4bf9c33 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 17:18:09 +0800 Subject: [PATCH 61/69] =?UTF-8?q?Update=200240-=E6=90=9C=E7=B4=A2=E4=BA=8C?= =?UTF-8?q?=E7=BB=B4=E7=9F=A9=E9=98=B5II.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\347\273\264\347\237\251\351\230\265II.py" | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git "a/0240.\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II/0240-\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II.py" "b/0240.\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II/0240-\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II.py" index 155bcd6..892412c 100644 --- "a/0240.\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II/0240-\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II.py" +++ "b/0240.\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II/0240-\346\220\234\347\264\242\344\272\214\347\273\264\347\237\251\351\230\265II.py" @@ -1,16 +1,24 @@ -class Solution(object): - def searchMatrix(self, matrix, target): - """ - :type matrix: List[List[int]] - :type target: int - :rtype: bool - """ - if not matrix or not matrix[0]: - return False - m, n = len(matrix), len(matrix[0]) - - for i in range(m): - for j in range(n): - if matrix[i][j] == target: - return True - return False \ No newline at end of file +体思路是尽可能多的排除掉无关 行/列 ,可以从 第一排最后一个/第一列最后一个 开始搜索,这里选择从 第一排最后一个 开始 +由于行列规则等价,搜索策略 先按行排除/按列排除 也是等价的,这里选择 按行排除 +搜索规则:小于 target 则向左搜索,大于 则向下搜索,可以保证 global search +若超出 矩阵大小 则意味着没有匹配 target,输出 False + +class Solution: + def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: + row = len(matrix) + col = len(matrix[0]) + i = 0 + j = col - 1 + while matrix[i][j] != target: + if matrix[i][j] < target: + i += 1 + else: + j -= 1 + if i >= row or j < 0: + return False + return True + +作者:Eloise +链接:https://leetcode.cn/problems/search-a-2d-matrix-ii/solutions/618999/si-lu-qing-xi-zhe-xian-sou-suo-by-eloise-kisj/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From daea31f295c0a379f0372c091b54a443aa6ad76e Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 17:21:40 +0800 Subject: [PATCH 62/69] =?UTF-8?q?Update=200279-=E5=AE=8C=E5=85=A8=E5=B9=B3?= =?UTF-8?q?=E6=96=B9=E6=95=B0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...50\345\271\263\346\226\271\346\225\260.py" | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git "a/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" "b/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" index 7b6dda6..785e5d0 100644 --- "a/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" +++ "b/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" @@ -1,19 +1,22 @@ -class Solution(object): - def numSquares(self, n): - """ - :type n: int - :rtype: int - """ - from collections import deque - queue = deque([(0, 0)]) - visited = set() - while queue: - cur, step = queue.popleft() - for i in range(1, int(n ** 0.5) + 1): - s = cur + i ** 2 - if s == n: - return step + 1 - if s not in visited: - visited.add(s) - queue.append((s, step + 1)) - \ No newline at end of file +dp[i]表示iii最少可以由几个平方数构成。 + +1 初试化dp=[0,1,2,⋯ ,n],长度为n+1,最多次数就是全由1构成。 + +2 遍历dp,对于i,遍历区间[2,n+1): + 遍历所有平方数小于i的数j,遍历区间[1,int(sqrt(i))+1) + dp[i]=min(dp[i],dp[i−j∗j]+1)。始终保存所有可能情况中的最小值。 +3 返回dp[n] + +class Solution: + def numSquares(self, n: int) -> int: + dp=[i for i in range(n+1)] + for i in range(2,n+1): + for j in range(1,int(i**(0.5))+1): + dp[i]=min(dp[i],dp[i-j*j]+1) + return dp[-1] + +作者:吴彦祖 +链接:https://leetcode.cn/problems/perfect-squares/solutions/54142/dong-tai-gui-hua-bfs-zhu-xing-jie-shi-python3-by-2/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 + From 57b28ddea5d4c924f666e3e32d5c61c6d8fbc4f9 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 17:22:06 +0800 Subject: [PATCH 63/69] =?UTF-8?q?Update=200279-=E5=AE=8C=E5=85=A8=E5=B9=B3?= =?UTF-8?q?=E6=96=B9=E6=95=B0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" "b/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" index 785e5d0..7d488ee 100644 --- "a/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" +++ "b/0279.\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260/0279-\345\256\214\345\205\250\345\271\263\346\226\271\346\225\260.py" @@ -1,4 +1,4 @@ -dp[i]表示iii最少可以由几个平方数构成。 +dp[i]表示i最少可以由几个平方数构成。 1 初试化dp=[0,1,2,⋯ ,n],长度为n+1,最多次数就是全由1构成。 From 7250c1da348e9abb34594562dd68b2c780a8598f Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 17:25:37 +0800 Subject: [PATCH 64/69] =?UTF-8?q?Update=200283-=E7=A7=BB=E5=8A=A8=E9=9B=B6?= =?UTF-8?q?.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...3-\347\247\273\345\212\250\351\233\266.py" | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git "a/0283.\347\247\273\345\212\250\351\233\266/0283-\347\247\273\345\212\250\351\233\266.py" "b/0283.\347\247\273\345\212\250\351\233\266/0283-\347\247\273\345\212\250\351\233\266.py" index 897a7c7..7dbb1bf 100644 --- "a/0283.\347\247\273\345\212\250\351\233\266/0283-\347\247\273\345\212\250\351\233\266.py" +++ "b/0283.\347\247\273\345\212\250\351\233\266/0283-\347\247\273\345\212\250\351\233\266.py" @@ -1,13 +1,19 @@ -class Solution(object): - def moveZeroes(self, nums): +# 双指针滑动,交换非零元素和零元素的位置 +class Solution: + def moveZeroes(self, nums: List[int]) -> None: """ - :type nums: List[int] - :rtype: None Do not return anything, modify nums in-place instead. + Do not return anything, modify nums in-place instead. """ - i = 0 + # 循环遍历数组,当遇到非零元素则开始交换慢指针所指的0元素 + # i 为慢指针 指向最新一个0元素的位置 + i = 0 for j in range(len(nums)): if nums[j] != 0: nums[i], nums[j] = nums[j], nums[i] i += 1 - - # return nums \ No newline at end of file + return nums + +作者:sunfox +链接:https://leetcode.cn/problems/move-zeroes/solutions/168920/pythonti-san-chong-jie-fa-kuai-lai-kan-by-sunfox/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 9cdddfe89bc1879b27671ee740a03144ce30d0ad Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 17:34:01 +0800 Subject: [PATCH 65/69] =?UTF-8?q?Update=200287-=E5=AF=BB=E6=89=BE=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E6=95=B0.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...76\351\207\215\345\244\215\346\225\260.py" | 51 +++++++++++++------ 1 file changed, 35 insertions(+), 16 deletions(-) diff --git "a/0287.\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260/0287-\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260.py" "b/0287.\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260/0287-\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260.py" index 6e077e2..6dc2dc8 100644 --- "a/0287.\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260/0287-\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260.py" +++ "b/0287.\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260/0287-\345\257\273\346\211\276\351\207\215\345\244\215\346\225\260.py" @@ -1,16 +1,35 @@ -class Solution(object): - def findDuplicate(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - slow, fast = 0, 0 - while 1: - slow = nums[slow] - fast = nums[nums[fast]] - if slow == fast: - fast = 0 - while nums[slow] != nums[fast]: - slow = nums[slow] - fast = nums[fast] - return nums[fast] \ No newline at end of file +按题目表达,设数组长度为n,则数组中元素∈[1,n−1],且只有一个重复元素。 +一个直观的想法,设一个数字k∈[1,n−1],统计数组中小于等于k的数字的个数count: + +若count<=k,说明重复数字一定在(k,n−1]范围内。 +若count>k,说明重复数字一定在[0,k]的范围内。 +利用这个性质,我们使用二分查找逐渐缩小重复数字所在的范围。 + +1 初试化左右 数字 边界left=1,right=n−1 +2 循环条件leftmid,说明重复数字一定在[left,mid]的范围内。令right=mid。 +3 返回left + +class Solution: + def findDuplicate(self, nums: List[int]) -> int: + left = 1 + right = len(nums) - 1 + while(left Date: Mon, 5 Jun 2023 17:40:50 +0800 Subject: [PATCH 66/69] =?UTF-8?q?Update=200300-=E6=9C=80=E9=95=BF=E4=B8=8A?= =?UTF-8?q?=E5=8D=87=E5=AD=90=E5=BA=8F=E5=88=97.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...07\345\255\220\345\272\217\345\210\227.py" | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git "a/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227/0300-\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" "b/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227/0300-\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" index f5fcf2e..5036c2f 100644 --- "a/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227/0300-\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" +++ "b/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227/0300-\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.py" @@ -1,14 +1,30 @@ -class Solution(object): - def lengthOfLIS(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - dp = [1 for _ in nums] - +状态定义: +dp[i]的值代表 nums 以 nums[i] 结尾的最长子序列长度。 + +转移方程: 设 j∈[0,i),考虑每轮计算新 dp[i]dp[i]dp[i] 时,遍历 [0,i) 列表区间,做以下判断: + 1.当 nums[i]>nums[j] 时: nums[i] 可以接在 nums[j] 之后(此题要求严格递增),此情况下最长上升子序列长度为 dp[j]+1; + 2.当 nums[i]<=nums[j] 时: nums[i] 无法接在 nums[j] 之后,此情况上升子序列不成立,跳过。 + 上述所有 1. 情况 下计算出的 dp[j]+1 的最大值,为直到 i 的最长上升子序列长度(即 dp[i])。实现方式为遍历 j 时,每轮执行 dp[i]=max(dp[i],dp[j]+1)。 + 转移方程: dp[i] = max(dp[i], dp[j] + 1) for j in [0, i)。 + +初始状态: +dp[i] 所有元素置 1,含义是每个元素都至少可以单独成为子序列,此时长度都为 1。 + +返回值: +返回 dp 列表最大值,即可得到全局最长上升子序列长度。 + +# Dynamic programming. +class Solution: + def lengthOfLIS(self, nums: List[int]) -> int: + if not nums: return 0 + dp = [1] * len(nums) for i in range(len(nums)): for j in range(i): - if nums[i] > nums[j]: + if nums[j] < nums[i]: # 如果要求非严格递增,将此行 '<' 改为 '<=' 即可。 dp[i] = max(dp[i], dp[j] + 1) - - return max(dp) if dp else 0 \ No newline at end of file + return max(dp) + +作者:Krahets +链接:https://leetcode.cn/problems/longest-increasing-subsequence/solutions/24173/zui-chang-shang-sheng-zi-xu-lie-dong-tai-gui-hua-2/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 8d65383ab5eb3aca540c43eb553da84c7d0fbe87 Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 18:25:22 +0800 Subject: [PATCH 67/69] =?UTF-8?q?Update=200581-=E6=9C=80=E7=9F=AD=E6=97=A0?= =?UTF-8?q?=E5=BA=8F=E8=BF=9E=E7=BB=AD=E5=AD=90=E6=95=B0=E7=BB=84.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...55\345\255\220\346\225\260\347\273\204.py" | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git "a/0581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/0581-\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" "b/0581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/0581-\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" index 33bc985..7b50680 100644 --- "a/0581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/0581-\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" +++ "b/0581.\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204/0581-\346\234\200\347\237\255\346\227\240\345\272\217\350\277\236\347\273\255\345\255\220\346\225\260\347\273\204.py" @@ -1,19 +1,18 @@ -class Solution(object): - def findUnsortedSubarray(self, nums): - """ - :type nums: List[int] - :rtype: int - """ - s = sorted(nums) - if s == nums: - return 0 - for i in range(len(s)): - if s[i] != nums[i]: - break - for j in range(len(s) - 1, -1, -1): - if s[j] != nums[j]: - break - # print i, j - # print s, nums - return len(s) - i - (len(s) - 1 -j) - \ No newline at end of file +# 很自然的想法,将原数组copy并排序,和原数组比对。 + +class Solution: + def findUnsortedSubarray(self, nums: List[int]) -> int: + nums_copy=nums[:] + nums_copy.sort() + left=float("inf") + right=0 + for i in range(len(nums)): + if(nums_copy[i]!=nums[i]): + left=min(left,i) + right=max(right,i) + return right-left+1 if(right-left+1 > 0) else 0 + +作者:吴彦祖 +链接:https://leetcode.cn/problems/shortest-unsorted-continuous-subarray/solutions/45188/liang-ci-bian-li-pai-xu-bi-dui-python3-by-zhu_shi_/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 4c8e128082fa658c7206b1fd9462dbc44c3bec9d Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 18:29:08 +0800 Subject: [PATCH 68/69] =?UTF-8?q?Update=200739-=E6=AF=8F=E6=97=A5=E6=B8=A9?= =?UTF-8?q?=E5=BA=A6.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...17\346\227\245\346\270\251\345\272\246.py" | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git "a/0739.\346\257\217\346\227\245\346\270\251\345\272\246/0739-\346\257\217\346\227\245\346\270\251\345\272\246.py" "b/0739.\346\257\217\346\227\245\346\270\251\345\272\246/0739-\346\257\217\346\227\245\346\270\251\345\272\246.py" index c13dac5..f2d5213 100644 --- "a/0739.\346\257\217\346\227\245\346\270\251\345\272\246/0739-\346\257\217\346\227\245\346\270\251\345\272\246.py" +++ "b/0739.\346\257\217\346\227\245\346\270\251\345\272\246/0739-\346\257\217\346\227\245\346\270\251\345\272\246.py" @@ -1,15 +1,18 @@ -class Solution(object): - def dailyTemperatures(self, T): - """ - :type T: List[int] - :rtype: List[int] - """ - res = [0] * len(T) - s = [] - # print res - for i in range(0, len(T)): - while(s and T[i] > T[s[-1]]): - res[s[-1]] = i - s[-1] - s.pop() - s.append(i) - return res \ No newline at end of file +# 单调栈解法 +class Solution: + def dailyTemperatures(self, T: List[int]) -> List[int]: + # 可以维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列表中的温度依次递减。 + # 如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标。 + ans = [0] * len(T) + stack = [] + for i in range(len(T)): + while stack and T[stack[-1]] < T[i]: # 栈不为空 && 栈顶温度小于当前温度 + ans[stack[-1]] = i - stack[-1] + stack.pop() + stack.append(i) + return ans + +# 作者:dz-lee +# 链接:https://leetcode.cn/problems/daily-temperatures/solutions/284113/dan-diao-zhan-cong-hou-xiang-qian-bian-li-python3x/ +# 来源:力扣(LeetCode) +# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 From 6bb320fc9d9a04ffc7aa29e6404cf2887565810b Mon Sep 17 00:00:00 2001 From: zaie <948064756@qq.com> Date: Mon, 5 Jun 2023 18:42:26 +0800 Subject: [PATCH 69/69] =?UTF-8?q?Update=200994-=E8=85=90=E7=83=82=E7=9A=84?= =?UTF-8?q?=E6=A9=98=E5=AD=90.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...02\347\232\204\346\251\230\345\255\220.py" | 62 +++++++------------ 1 file changed, 21 insertions(+), 41 deletions(-) diff --git "a/0994.\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220/0994-\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220.py" "b/0994.\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220/0994-\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220.py" index 5d9ce8b..aac857b 100644 --- "a/0994.\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220/0994-\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220.py" +++ "b/0994.\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220/0994-\350\205\220\347\203\202\347\232\204\346\251\230\345\255\220.py" @@ -1,43 +1,23 @@ -class Solution(object): - def orangesRotting(self, grid): - """ - :type grid: List[List[int]] - :rtype: int - """ - from collections import deque - if not grid or not grid[0]: - return 0 - - m, n = len(grid), len(grid[0]) - dx = [1, -1, 0, 0] - dy = [0, 0, 1, -1] - - queue = deque() - for i in range(m): - for j in range(n): - if grid[i][j] == 2: - queue.append((i, j)) +1. 首先分别将腐烂的橘子和新鲜的橘子保存在两个集合中; +2. 模拟广度优先搜索的过程,方法是判断在每个腐烂橘子的四个方向上是否有新鲜橘子,如果有就腐烂它。 +每腐烂一次时间加 1,并剔除新鲜集合里腐烂的橘子; +3. 当橘子全部腐烂时结束循环。 - res = 0 - while queue: - for i in range(len(queue)): - pair = queue.popleft() - x0, y0 = pair[0], pair[1] - for k in range(4): - x = x0 + dx[k] - y = y0 + dy[k] +class Solution: + def orangesRotting(self, grid: List[List[int]]) -> int: + row = len(grid) + col = len(grid[0]) + rotten = {(i, j) for i in range(row) for j in range(col) if grid[i][j] == 2} # 腐烂集合 + fresh = {(i, j) for i in range(row) for j in range(col) if grid[i][j] == 1} # 新鲜集合 + time = 0 + while fresh: + if not rotten: return -1 + rotten = {(i + di, j + dj) for i, j in rotten for di, dj in [(0, 1), (0, -1), (1, 0), (-1, 0)] if (i + di, j + dj) in fresh} # 即将腐烂的如果在新鲜的集合中,就将它腐烂 + fresh -= rotten # 剔除腐烂的 + time += 1 + return time - if 0 <= x < m and 0 <= y < n and grid[x][y] == 1: - grid[x][y] = 2 - queue.append((x, y)) - if not queue: - break - res += 1 - for i in range(m): - for j in range(n): - if grid[i][j] == 1: - return -1 - return res - - - \ No newline at end of file +作者:z1m +链接:https://leetcode.cn/problems/rotting-oranges/solution/yan-du-you-xian-sou-suo-python3-c-by-z1m/ +来源:力扣(LeetCode) +著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。