mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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()) # 如果一开始只有一个数,那么会是字符串形式的
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(n)
|
||||
因此这里使用双向队列,我们保证只执行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
|
||||
|
||||
```
|
||||
|
||||
|
@ -281,48 +281,60 @@ 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.empty:
|
||||
return None
|
||||
|
||||
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.empty:
|
||||
return None
|
||||
|
||||
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)
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
```
|
||||
|
||||
|
||||
|
@ -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:
|
||||
res.pop()
|
||||
else:
|
||||
t.append(i)
|
||||
return "".join(t) # 字符串拼接
|
||||
res.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:
|
||||
|
@ -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)
|
||||
|
||||
```
|
||||
|
||||
|
@ -125,24 +125,45 @@ 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:
|
||||
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 = ''
|
||||
|
Reference in New Issue
Block a user