From 7c6930971d6175fe6656a4b31c4ac1c6d765d795 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 15:00:28 +0800 Subject: [PATCH 01/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200203.=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0.md=20python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用更符合PEP8要求的代码规范来约束 --- problems/0203.移除链表元素.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index f3724fc2..d67a7d2a 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -245,13 +245,15 @@ Python: # def __init__(self, val=0, next=None): # self.val = val # self.next = next + class Solution: def removeElements(self, head: ListNode, val: int) -> ListNode: - dummy_head = ListNode(next=head) #添加一个虚拟节点 + dummy_head = ListNode(next=head) cur = dummy_head - while(cur.next!=None): - if(cur.next.val == val): - cur.next = cur.next.next #删除cur.next节点 + + while cur.next: + if cur.next.val == val: + cur.next = cur.next.next # 删除下一个节点 else: cur = cur.next return dummy_head.next From f6eee532e49acba882be2b202825ee7082d9a69c Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:26:42 +0800 Subject: [PATCH 02/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200344.=E5=8F=8D?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2.md=20python=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BC=98=E5=8C=96=EF=BC=8C=E5=88=A0=E9=99=A4=E5=8F=A6?= =?UTF-8?q?=E4=B8=80=E7=A7=8D=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 另一种解法进行了不必要的操作,且代码可读性较差。 推荐使用第一种解法 --- problems/0344.反转字符串.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index 4f96f839..763097be 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -162,21 +162,14 @@ class Solution: Do not return anything, modify s in-place instead. """ left, right = 0, len(s) - 1 - while(left < right): + + # 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(right//2)更低 + # 推荐该写法,更加通俗易懂 + while left < right: s[left], s[right] = s[right], s[left] left += 1 right -= 1 - -# 下面的写法更加简洁,但是都是同样的算法 -# class Solution: -# def reverseString(self, s: List[str]) -> None: -# """ -# Do not return anything, modify s in-place instead. -# """ - # 不需要判别是偶数个还是奇数个序列,因为奇数个的时候,中间那个不需要交换就可 -# for i in range(len(s)//2): -# s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i] -# return s + ``` Go: From e6571ecaac55a91a557b32248560ef5fac612cf1 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 17:30:36 +0800 Subject: [PATCH 03/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200541.=E5=8F=8D?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2II.md=20python=E9=83=A8?= =?UTF-8?q?=E5=88=86=EF=BC=8C=E5=8E=BB=E9=99=A4=E8=87=AA=E9=80=A0=E8=BD=AE?= =?UTF-8?q?=E5=AD=90=E9=83=A8=E5=88=86=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 维持原方法的思路,简化了包和匿名函数的用法 原代码使用了reduce包 + 匿名函数来实现 ''.join的操作,去除该部分提升运行效率 --- problems/0541.反转字符串II.md | 35 ++++++++++++------------------ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index ab1ef16a..02713c65 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -155,34 +155,27 @@ class Solution { Python: ```python - -class Solution(object): - def reverseStr(self, s, k): +class Solution: + def reverseStr(self, s: str, k: int) -> str: """ - :type s: str - :type k: int - :rtype: str + 1. 使用range(start, end, step)来确定需要调换的初始位置 + 2. 对于字符串s = 'abc',如果使用s[0:999] ===> 'abc'。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理。 + 3. 用切片整体替换,而不是一个个替换. """ - from functools import reduce - # turn s into a list - s = list(s) - - # another way to simply use a[::-1], but i feel this is easier to understand - def reverse(s): - left, right = 0, len(s) - 1 + def reverse_substring(text): + left, right = 0, len(text) - 1 while left < right: - s[left], s[right] = s[right], s[left] + text[left], text[right] = text[right], text[left] left += 1 right -= 1 - return s + return text - # make sure we reverse each 2k elements - for i in range(0, len(s), 2*k): - s[i:(i+k)] = reverse(s[i:(i+k)]) - - # combine list into str. - return reduce(lambda a, b: a+b, s) + res = list(s) + + for cur in range(0, len(s), 2 * k): + res[cur: cur + k] = reverse_substring(res[cur: cur + k]) + return ''.join(res) ``` From 51e719a4351fb97ed41ad6995bc6470d5204ad35 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 17:57:39 +0800 Subject: [PATCH 04/16] =?UTF-8?q?=E7=AE=80=E5=8C=96=20=E5=89=91=E6=8C=87Of?= =?UTF-8?q?fer05.=E6=9B=BF=E6=8D=A2=E7=A9=BA=E6=A0=BC.md=20python=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 减少不必要的变量使用,优化空间复杂度,使用切片替换而不是单个替换 --- problems/剑指Offer05.替换空格.md | 58 +++++++++----------------- 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/problems/剑指Offer05.替换空格.md b/problems/剑指Offer05.替换空格.md index 4ae5f9f2..3f373d0d 100644 --- a/problems/剑指Offer05.替换空格.md +++ b/problems/剑指Offer05.替换空格.md @@ -202,45 +202,27 @@ func replaceSpace(s string) string { python: ```python -class Solution(object): - def replaceSpace(self, s): - """ - :type s: str - :rtype: str - """ - list_s = list(s) - - # 记录原本字符串的长度 - original_end = len(s) - - # 将空格改成%20 使得字符串总长增长 2n,n为原本空格数量。 - # 所以记录空格数量就可以得到目标字符串的长度 - n_space = 0 - for ss in s: - if ss == ' ': - n_space += 1 - - list_s += ['0'] * 2 * n_space - - # 设置左右指针位置 - left, right = original_end - 1, len(list_s) - 1 - - # 循环直至左指针越界 - while left >= 0: - if list_s[left] == ' ': - list_s[right] = '0' - list_s[right - 1] = '2' - list_s[right - 2] = '%' - right -= 3 - else: - list_s[right] = list_s[left] - right -= 1 - - left -= 1 +class Solution: + def replaceSpace(self, s: str) -> str: + counter = s.count(' ') - # 将list变回str,输出 - s = ''.join(list_s) - return s + res = list(s) + # 每碰到一个空格就多拓展两个格子,1 + 2 = 3个位置存’%20‘ + res.extend([' '] * counter * 2) + + # 原始字符串的末尾,拓展后的末尾 + left, right = len(s) - 1, len(res) - 1 + + while left >= 0: + if res[left] != ' ': + res[right] = res[left] + right -= 1 + else: + # [right - 2, right), 左闭右开 + res[right - 2: right + 1] = '%20' + right -= 3 + left -= 1 + return ''.join(res) ``` From 6255eae04cefc676d243bc53ea4070bc900b3c99 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 21:01:20 +0800 Subject: [PATCH 05/16] =?UTF-8?q?=E8=A1=A5=E5=85=85=20=E5=89=91=E6=8C=87Of?= =?UTF-8?q?fer58-II.=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?.md=20python=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 如果不让使用自带函数reversed() 可以使用该方法 --- problems/剑指Offer58-II.左旋转字符串.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 1073dafa..6070f85b 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -136,13 +136,28 @@ class Solution: # return "".join(s) +# 方法三:如果连reversed也不让使用,那么自己手写一个 +class Solution: + def reverseLeftWords(self, s: str, n: int) -> str: + def reverse_sub(lst, left, right): + while left < right: + lst[left], lst[right] = lst[right], lst[left] + left += 1 + right -= 1 + + res = list(s) + end = len(res) - 1 + reverse_sub(res, 0, n - 1) + reverse_sub(res, n, end) + reverse_sub(res, 0, end) + return ''.join(res) # 时间复杂度:O(n) # 空间复杂度:O(n),python的string为不可变,需要开辟同样大小的list空间来修改 ``` ```python 3 -#方法三:考虑不能用切片的情况下,利用模+下标实现 +#方法四:考虑不能用切片的情况下,利用模+下标实现 class Solution: def reverseLeftWords(self, s: str, n: int) -> str: new_s = '' From 1a82f98a175ab03569c67a436b093203ab343d20 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 21:04:57 +0800 Subject: [PATCH 06/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E5=89=91=E6=8C=87Of?= =?UTF-8?q?fer58-II.=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?.md=20=E6=A0=BC=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新排版 --- .../剑指Offer58-II.左旋转字符串.md | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 6070f85b..15607a50 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -125,17 +125,21 @@ python: class Solution: def reverseLeftWords(self, s: str, n: int) -> str: return s[n:] + s[0:n] - +``` +```python # 方法二:也可以使用上文描述的方法,有些面试中不允许使用切片,那就使用上文作者提到的方法 -# class Solution: -# def reverseLeftWords(self, s: str, n: int) -> str: -# s = list(s) -# s[0:n] = list(reversed(s[0:n])) -# s[n:] = list(reversed(s[n:])) -# s.reverse() +class Solution: + def reverseLeftWords(self, s: str, n: int) -> str: + s = list(s) + s[0:n] = list(reversed(s[0:n])) + s[n:] = list(reversed(s[n:])) + s.reverse() + + return "".join(s) -# return "".join(s) +``` +```python # 方法三:如果连reversed也不让使用,那么自己手写一个 class Solution: def reverseLeftWords(self, s: str, n: int) -> str: @@ -152,8 +156,10 @@ class Solution: reverse_sub(res, 0, end) return ''.join(res) +# 同方法二 # 时间复杂度:O(n) # 空间复杂度:O(n),python的string为不可变,需要开辟同样大小的list空间来修改 + ``` ```python 3 From a69006f901230b1ba73e73ce8b86918b404480e4 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 00:06:33 +0800 Subject: [PATCH 07/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200232.=E7=94=A8?= =?UTF-8?q?=E6=A0=88=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97.md=20python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit python代码简化,符合PEP8标准,可读性加强,效率提升 --- problems/0232.用栈实现队列.md | 50 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 0df82d35..46d884d3 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -281,48 +281,54 @@ class MyQueue { Python: ```python -# 使用两个栈实现先进先出的队列 class MyQueue: + def __init__(self): """ - Initialize your data structure here. + in主要负责push,out主要负责pop """ - self.stack1 = list() - self.stack2 = list() + self.stack_in = [] + self.stack_out = [] + def push(self, x: int) -> None: """ - Push element x to the back of queue. + 有新元素进来,就往in里面push """ - # self.stack1用于接受元素 - self.stack1.append(x) + self.stack_in.append(x) + def pop(self) -> int: """ - Removes the element from in front of queue and returns that element. + 1. 检查如果out里面元素,则直接pop + 2. 如果out没有元素,就把in里面的元素(除了第一个)依次pop后装进out里面 + 3. 直接把in剩下的元素pop出来,就是queue头部的 """ - # self.stack2用于弹出元素,如果self.stack2为[],则将self.stack1中元素全部弹出给self.stack2 - if self.stack2 == []: - while self.stack1: - tmp = self.stack1.pop() - self.stack2.append(tmp) - return self.stack2.pop() + if self.stack_out: + return self.stack_out.pop() + else: + for i in range(1, len(self.stack_in)): + self.stack_out.append(self.stack_in.pop()) + return self.stack_in.pop() + def peek(self) -> int: """ - Get the front element. + 1. 查out有没有元素,有就把最上面的返回 + 2. 如果out没有元素,就把in最下面的返回 """ - if self.stack2 == []: - while self.stack1: - tmp = self.stack1.pop() - self.stack2.append(tmp) - return self.stack2[-1] + if self.stack_out: + return self.stack_out[-1] + else: + return self.stack_in[0] + def empty(self) -> bool: """ - Returns whether the queue is empty. + 只要in或者out有元素,说明队列不为空 """ - return self.stack1 == [] and self.stack2 == [] + return not (self.stack_in or self.stack_out) + ``` From 77e789a248dc21b8b939ee37e0d5d58512e90d8d Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:49:06 +0800 Subject: [PATCH 08/16] =?UTF-8?q?=E7=AE=80=E5=8C=96=200225.=E7=94=A8?= =?UTF-8?q?=E9=98=9F=E5=88=97=E5=AE=9E=E7=8E=B0=E6=A0=88.md=20python?= =?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=8C=E5=86=97=E4=BD=99=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=A4=AA=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原方法用了很多不必要的变量和操作,改进后的代码更直观,效率和空间都得到了优化 --- problems/0225.用队列实现栈.md | 65 +++++++++++++++++------------ 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index b327c17b..d82220db 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -294,53 +294,66 @@ Python: ```python from collections import deque + class MyStack: + def __init__(self): """ - Initialize your data structure here. + Python普通的Queue或SimpleQueue没有类似于peek的功能 + 也无法用索引访问,在实现top的时候较为困难。 + + 用list可以,但是在使用pop(0)的时候时间复杂度为O(1) + 因此这里使用双向队列,我们保证只执行popleft()和append(),因为deque可以用索引访问,可以实现和peek相似的功能 + + in - 存所有数据 + out - 仅在pop的时候会用到 """ - #使用两个队列来实现 - self.que1 = deque() - self.que2 = deque() + self.queue_in = deque() + self.queue_out = deque() def push(self, x: int) -> None: """ - Push element x onto stack. + 直接append即可 """ - self.que1.append(x) + self.queue_in.append(x) + def pop(self) -> int: """ - Removes the element on top of the stack and returns that element. + 1. 首先确认不空 + 2. 因为队列的特殊性,FIFO,所以我们只有在pop()的时候才会使用queue_out + 3. 先把queue_in中的所有元素(除了最后一个),依次出列放进queue_out + 4. 交换in和out,此时out里只有一个元素 + 5. 把out中的pop出来,即是原队列的最后一个 + + tip:这不能像栈实现队列一样,因为另一个queue也是FIFO,如果执行pop()它不能像 + stack一样从另一个pop(),所以干脆in只用来存数据,pop()的时候两个进行交换 """ - size = len(self.que1) - size -= 1#这里先减一是为了保证最后面的元素 - while size > 0: - size -= 1 - self.que2.append(self.que1.popleft()) + if self.empty(): + return None - - result = self.que1.popleft() - self.que1, self.que2= self.que2, self.que1#将que2和que1交换 que1经过之前的操作应该是空了 - #一定注意不能直接使用que1 = que2 这样que2的改变会影响que1 可以用浅拷贝 - return result + for i in range(len(self.queue_in) - 1): + self.queue_out.append(self.queue_in.popleft()) + + self.queue_in, self.queue_out = self.queue_out, self.queue_in # 交换in和out,这也是为啥in只用来存 + return self.queue_out.popleft() def top(self) -> int: """ - Get the top element. + 1. 首先确认不空 + 2. 我们仅有in会存放数据,所以返回第一个即可 """ - return self.que1[-1] + if self.empty(): + return None + + return self.queue_in[-1] + def empty(self) -> bool: """ - Returns whether the stack is empty. + 因为只有in存了数据,只要判断in是不是有数即可 """ - #print(self.que1) - if len(self.que1) == 0: - return True - else: - return False - + return len(self.queue_in) == 0 ``` From 55eb649434a95116e0fdcde2a89db5be1f85d801 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:50:53 +0800 Subject: [PATCH 09/16] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=200225.=E7=94=A8?= =?UTF-8?q?=E9=98=9F=E5=88=97=E5=AE=9E=E7=8E=B0=E6=A0=88.md=EF=BC=8Cdoc?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 时间复杂度错误,修正 --- problems/0225.用队列实现栈.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index d82220db..ccf93f1f 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -302,7 +302,7 @@ class MyStack: Python普通的Queue或SimpleQueue没有类似于peek的功能 也无法用索引访问,在实现top的时候较为困难。 - 用list可以,但是在使用pop(0)的时候时间复杂度为O(1) + 用list可以,但是在使用pop(0)的时候时间复杂度为O(n) 因此这里使用双向队列,我们保证只执行popleft()和append(),因为deque可以用索引访问,可以实现和peek相似的功能 in - 存所有数据 From 571defa00789aa9764abb6aa7efe54944ed42a49 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:15:03 +0800 Subject: [PATCH 10/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200020.=E6=9C=89?= =?UTF-8?q?=E6=95=88=E7=9A=84=E6=8B=AC=E5=8F=B7.md=20python=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=A2=9D=E5=A4=96=E6=96=B9=E6=B3=95=E6=8F=90=E4=BE=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充了题主的方法,改写了原先冗余的做法,可读性提升,PEP8标准 --- problems/0020.有效的括号.md | 44 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md index a26aa308..57729c38 100644 --- a/problems/0020.有效的括号.md +++ b/problems/0020.有效的括号.md @@ -162,18 +162,44 @@ class Solution { Python: ```python3 +# 方法一,仅使用栈,更省空间 class Solution: def isValid(self, s: str) -> bool: - stack = [] # 保存还未匹配的左括号 - mapping = {")": "(", "]": "[", "}": "{"} - for i in s: - if i in "([{": # 当前是左括号,则入栈 - stack.append(i) - elif stack and stack[-1] == mapping[i]: # 当前是配对的右括号则出栈 - stack.pop() - else: # 不是匹配的右括号或者没有左括号与之匹配,则返回false + stack = [] + + for item in s: + if item == '(': + stack.append(')') + elif item == '[': + stack.append(']') + elif item == '{': + stack.append('}') + elif not stack or stack[-1] != item: return False - return stack == [] # 最后必须正好把左括号匹配完 + else: + stack.pop() + + return True if not stack else False +``` + +```python3 +# 方法二,使用字典 +class Solution: + def isValid(self, s: str) -> bool: + stack = [] + mapping = { + '(': ')', + '[': ']', + '{': '}' + } + for item in s: + if item in mapping.keys(): + stack.append(mapping[item]) + elif not stack or stack[-1] != item: + return False + else: + stack.pop() + return True if not stack else False ``` Go: From ce2c6fb562ae22b2b18230d8f00202f67c89c696 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:55:31 +0800 Subject: [PATCH 11/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0+=E8=A1=A5=E5=85=85=201?= =?UTF-8?q?047.=E5=88=A0=E9=99=A4=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=89=80=E6=9C=89=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E9=A1=B9.md=20python=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充使用双指针的方法,但是更推荐栈的做法 --- ...除字符串中的所有相邻重复项.md | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index c4ae85c9..7b059d40 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -197,15 +197,38 @@ class Solution { Python: ```python3 +# 方法一,使用栈,推荐! class Solution: def removeDuplicates(self, s: str) -> str: - t = list() - for i in s: - if t and t[-1] == i: - t.pop(-1) + res = list() + for item in s: + if res and res[-1] == item: + t.pop() else: - t.append(i) - return "".join(t) # 字符串拼接 + t.append(item) + return "".join(res) # 字符串拼接 +``` + +```python3 +# 双指针 +class Solution: + def removeDuplicates(self, s: str) -> str: + res = list(s) + slow = fast = 0 + length = len(res) + + while fast < length: + # 如果一样直接换,不一样会把后面的填在slow的位置 + res[slow] = res[fast] + + # 如果发现和前一个一样,就退一格指针 + if slow > 0 and res[slow] == res[slow - 1]: + slow -= 1 + else: + slow += 1 + fast += 1 + + return ''.join(res[0: slow]) ``` Go: From 13293e8c2f0e30743848e632244cc1a112e0422c Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:58:09 +0800 Subject: [PATCH 12/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=201047.=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D=E9=A1=B9.md=20pyt?= =?UTF-8?q?hon=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1047.删除字符串中的所有相邻重复项.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 7b059d40..1d63e7f8 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -210,7 +210,7 @@ class Solution: ``` ```python3 -# 双指针 +# 方法二,使用双指针模拟栈,如果不让用栈可以作为备选方法。 class Solution: def removeDuplicates(self, s: str) -> str: res = list(s) From 5e3d23fa38c78b9e66f12bd0e768968d7f31ed6c Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:59:10 +0800 Subject: [PATCH 13/16] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=201047.=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D=E9=A1=B9.md=20pyt?= =?UTF-8?q?hon=E6=96=B9=E6=B3=95=E4=B8=80=E4=BB=A3=E7=A0=81=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1047.删除字符串中的所有相邻重复项.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 1d63e7f8..b60a8d1d 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -203,9 +203,9 @@ class Solution: res = list() for item in s: if res and res[-1] == item: - t.pop() + res.pop() else: - t.append(item) + res.append(item) return "".join(res) # 字符串拼接 ``` From 8b94306cc6030eb79f2a8376b01f6398d888f7ed Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 03:23:30 +0800 Subject: [PATCH 14/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200024.=E4=B8=A4?= =?UTF-8?q?=E4=B8=A4=E4=BA=A4=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E8=8A=82=E7=82=B9.md=20python=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用变量名使交换的过程更加清晰,而不是使用之前的next.next这样可读性较差 从后往前换 pre = dummy,cur = 2, post=3 dummpy -> 1 -> 2 -> None 先把cur.next = post.next,此时链表为 1 -> None 再 post.next = cur 此时链表为 2 -> 1 -> None, dummpy -> 1 -> None 最后 pre.next = post, 此时为 dummpy -> 2 -> 1 -> None --- .../0024.两两交换链表中的节点.md | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 91e566dd..672b9a8f 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -160,21 +160,29 @@ class Solution { Python: ```python +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next + class Solution: def swapPairs(self, head: ListNode) -> ListNode: - dummy = ListNode(0) #设置一个虚拟头结点 - dummy.next = head - cur = dummy - while cur.next and cur.next.next: - tmp = cur.next #记录临时节点 - tmp1 = cur.next.next.next #记录临时节点 + res = ListNode(next=head) + pre = res + + # 必须有pre的下一个和下下个才能交换,否则说明已经交换结束了 + while pre.next and pre.next.next: + cur = pre.next + post = pre.next.next - cur.next = cur.next.next #步骤一 - cur.next.next = tmp #步骤二 - cur.next.next.next = tmp1 #步骤三 - - cur = cur.next.next #cur移动两位,准备下一轮交换 - return dummy.next + # pre,cur,post对应最左,中间的,最右边的节点 + cur.next = post.next + post.next = cur + pre.next = post + + pre = pre.next.next + return res.next ``` Go: From ca576c5bd0a62769c4b080028e7092d7fb945890 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 03:29:26 +0800 Subject: [PATCH 15/16] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=200232.=E7=94=A8?= =?UTF-8?q?=E6=A0=88=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97.md=20python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加限制条件,仅在栈不为空的情况下才允许后续pop()和peek()的操作 --- problems/0232.用栈实现队列.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 46d884d3..27a3de4e 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -304,6 +304,9 @@ class MyQueue: 2. 如果out没有元素,就把in里面的元素(除了第一个)依次pop后装进out里面 3. 直接把in剩下的元素pop出来,就是queue头部的 """ + if self.empty: + return None + if self.stack_out: return self.stack_out.pop() else: @@ -317,6 +320,9 @@ class MyQueue: 1. 查out有没有元素,有就把最上面的返回 2. 如果out没有元素,就把in最下面的返回 """ + if self.empty: + return None + if self.stack_out: return self.stack_out[-1] else: From 02fcd2c4a8f12782529b0fa787d3fd3f1f0fdca7 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 17:14:16 +0800 Subject: [PATCH 16/16] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200150.=E9=80=86?= =?UTF-8?q?=E6=B3=A2=E5=85=B0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=B1=82=E5=80=BC?= =?UTF-8?q?.md=20python=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用format string提升效率,增加可读性,避免使用索引访问,直接使用切片。 --- problems/0150.逆波兰表达式求值.md | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index 2b294337..bcde7d5b 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -223,17 +223,19 @@ var evalRPN = function(tokens) { python3 ```python -def evalRPN(tokens) -> int: - stack = list() - for i in range(len(tokens)): - if tokens[i] not in ["+", "-", "*", "/"]: - stack.append(tokens[i]) - else: - tmp1 = stack.pop() - tmp2 = stack.pop() - res = eval(tmp2+tokens[i]+tmp1) - stack.append(str(int(res))) - return stack[-1] +class Solution: + def evalRPN(self, tokens: List[str]) -> int: + stack = [] + for item in tokens: + if item not in {"+", "-", "*", "/"}: + stack.append(item) + else: + first_num, second_num = stack.pop(), stack.pop() + stack.append( + int(eval(f'{second_num} {item} {first_num}')) # 第一个出来的在运算符后面 + ) + return int(stack.pop()) # 如果一开始只有一个数,那么会是字符串形式的 + ```