数据结构(Python实现)------ 栈
数据结构(Python实现)------ 栈与队列
栈
基本概念
Python实现
基本的栈
class Stack(object):
def __init__(self):
self.data = []
def isEmpty(self):
return self.data == []
def push(self,newElem):
self.data.append(newElem)
def pop(self):
if self.isEmpty():
raise Exception("Your Stack is Empty!")
else:
return self.data.pop()
def top(self):
if self.isEmpty():
raise Exception("Your stack is Empty!")
else:
return self.data[len(self.data)-1]
def size(self):
return len(self.data)
最小栈
def __init__(self):
self.dataStack = Stack()
self.minStack = Stack()
def isEmpty(self):
return self.dataStack.data == []
def push(self,newElem):
self.dataStack.push(newElem)
if self.minStack.isEmpty():
self.minStack.push(newElem)
elif newElem <= self.minStack.top():
self.minStack.push(newElem)
def pop(self):
value = self.dataStack.pop()
if value == self.minStack.top():
self.minStack.pop()
return value
def top(self):
return self.dataStack.top()
def size(self):
return self.dataStack.size()
def getMin(self):
return self.minStack.top()
有效的括号
class Stack(object):
def __init__(self):
self.data = []
def isEmpty(self):
return self.data == []
def push(self,newElem):
self.data.append(newElem)
def pop(self):
if self.isEmpty():
raise Exception("Your stack is Empty!")
else:
self.data.pop()
def top(self):
return self.data[len(self.data)-1]
def size(self):
return len(self.data)
class Solution(object):
def isValid(self,s):
"""
:type s: str
:rtype: bool
"""
stack = Stack()
item ={'(':')','[':']','{':'}'}
if len(s) % 2 != 0:
return False
for i in s:
if i in item.keys():
stack.push(i)
elif i in item.values() and stack.isEmpty():
return False
elif i in item.values() and i == item[stack.top()]:
stack.pop()
return stack.isEmpty()
每日温度
stack = []
output = [0 for i in range(len(T))]
for index, value in enumerate(T):
# 空栈,直接把元素放入
if len(stack) == 0:
stack.append((index, value))
else:
# 扫描元素小于栈顶元素,入栈
if value < stack[-1][1]:
stack.append((index, value))
# 扫描元素大于栈顶元素,弹出栈顶元素并记录索引差值。
# 之后再判断与新的栈顶元素大小关系
else:
while (len(stack) > 0) and (value > stack[-1][1]):
index_pop, value_pop = stack.pop()
output[index_pop] = index - index_pop
#######
stack.append((index, value))
return output
逆波兰表达式求值
栈 与 DFS
基本概念
结点的处理顺序是什么?
在上面的例子中,我们从根结点 A 开始。首先,我们选择结点 B 的路径,并进行回溯,直到我们到达结点 E,我们无法更进一步深入。然后我们回溯到 A 并选择第二条路径到结点 C 。从 C 开始,我们尝试第一条路径到 E 但是 E 已被访问过。所以我们回到 C 并尝试从另一条路径到 F。最后,我们找到了 G。
总的来说,在我们到达最深的结点之后,我们只会回溯并尝试另一条路径。
栈的入栈和退栈顺序是什么?
如上面的动画所示,我们首先将根结点推入到栈中;然后我们尝试第一个邻居 B 并将结点 B 推入到栈中;等等等等。当我们到达最深的结点 E 时,我们需要回溯。当我们回溯时,我们将从栈中弹出最深的结点,这实际上是推入到栈中的最后一个结点。
结点的处理顺序是完全相反的顺序,就像它们被添加到栈中一样,它是后进先出(LIFO)。这就是我们在 DFS 中使用栈的原因。
Python实现
基本栈与DFS
深度优先遍历算法DFS通俗的说就是“顺着起点往下走,直到无路可走就退回去找下一条路径,直到走完所有的结点”。这里的“往下走”主是优先遍历结点的子结点。BFS与DFS都可以完成图的遍历。DFS常用到爬虫中,下面是最精简的代码:
def dfs(adj, start):
visited = set()
stack = [[start, 0]]
while stack:
(v, next_child_idx) = stack[-1]
if (v not in adj) or (next_child_idx >= len(adj[v])):
stack.pop()
continue
next_child = adj[v][next_child_idx]
stack[-1][1] += 1
if next_child in visited:
continue
print(next_child)
visited.add(next_child)
stack.append([next_child, 0])
graph = {1: [4, 2], 2: [3, 4], 3: [4], 4: [5]}
dfs(graph, 1)
岛屿数量
class Solution(object):
def numIslands(self,grid):
count = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j] == "1":
self.dfs(grid,i,j)
count += 1
return count
def dfs(self,grid,i,j):
if i < 0 or j <0 or i >= len(grid) or j >= len(grid[0]) or grid[i][j] != "1":
return
grid[i][j] = '#'
self.dfs(grid,i+1,j)
self.dfs(grid,i-1,j)
self.dfs(grid,i,j+1)
self.dfs(grid,i,j-1)
克隆图
class Solution(object):
def cloneGraph(self, node):
"""
:type node: Node
:rtype: Node
"""
if not node:
return None
new = Node(node.val, [])
visited = {node:new}
self.DFS(visited, node)
return new
def DFS(self, visited, node):
for i in node.neighbors:
if i not in visited:
visited[i] = Node(i.val, [])
self.DFS(visited, i)
visited[node].neighbors.append(visited[i])
目标和
注意这里只能用字典,如果光用list的话会超时,并且需要使用两个字典,一个做操作,一个做存储。
def findTargetSumWays(self, nums, S):
"""
:type nums: List[int]
:type S: int
:rtype: int
"""
lable1 = {0:1}
for num in nums:
lable2 = {}
for i in lable1:
if i + num in lable2:
lable2[i + num] += lable1[i]
else:
lable2[i + num] = lable1[i]
if i - num in lable2:
lable2[i - num] += lable1[i]
else:
lable2[i - num] = lable1[i]
lable1 = lable2
return lable2[S] if S in lable2 else 0
二叉树的中序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
ans = []
if root==None:
return ans
self.inTraverse(root,ans)
return ans
def inTraverse(self,t,ans):
if t.left:
self.inTraverse(t.left,ans)
ans.append(t.val)
if t.right:
self.inTraverse(t.right,ans)