python 常见算法面试题
部分参考:原网址有动图,能更好的理解。
菲波那切数列
# 生成器方式生成
def fib(max): # 传入一个值,输出比它小的数
a = 0
b = 1
while b<=max:
yield b
b,a = a+b,b
for i in fib(3524577):
print(i,end=' ')
二分查找
# 完整版 二分查找必须是有序的,
def find(l, aim, start=0, end=None):
if end == None: end = len(l) - 1
if start <= end:
mid = (end - start) // 2 + start
if l[mid] > aim:
return find(l, aim, start=start, end=mid - 1)
elif l[mid] < aim:
return find(l, aim, start=mid + 1, end=end)
elif l[mid] == aim:
return mid
else:
return None
l = [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88]
print('ret :', find(l, 66))
冒泡排序
l = [1, 2, 9, 34, 12, 5, 8]
def bubbleSort(l):
n = len(l)
for i in range(n):
for j in range(0, n - i - 1): # 每次循环会排好一个,所以每次减 i
if l[j] > l[j + 1]:
l[j], l[j + 1] = l[j + 1], l[j]
print(l)
bubbleSort(l)
快排
def partition(arr,low,high):
i = ( low-1 ) # 最小元素索引
pivot = arr[high]
for j in range(low , high):
# 当前元素小于或等于 pivot
if arr[j] <= pivot:
i = i+1
arr[i],arr[j] = arr[j],arr[i]
arr[i+1],arr[high] = arr[high],arr[i+1]
return ( i+1 )
# arr[] --> 排序数组
# low --> 起始索引
# high --> 结束索引
# 快速排序函数
def quickSort(arr,low,high):
if low < high:
pi = partition(arr,low,high)
quickSort(arr, low, pi-1)
quickSort(arr, pi+1, high)
arr = [10, 7, 8, 9, 1, 5]
n = len(arr)
quickSort(arr,0,n-1)
print ("排序后的数组:")
for i in range(n):
print ("%d" %arr[i]),
插入排序
def insertionSort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
arr = [12, 11, 13, 5, 6]
insertionSort(arr)
print ("排序后的数组:")
for i in range(len(arr)):
print ("%d" %arr[i])
选择排序
A = [64, 25, 12, 22, 11]
for i in range(len(A)):
min_idx = i
for j in range(i+1, len(A)):
if A[min_idx] > A[j]:
min_idx = j
A[i], A[min_idx] = A[min_idx], A[i]
print ("排序后的数组:")
for i in range(len(A)):
print("%d" %A[i]),
两个队列实现栈 参考
class StackWithTwoQueues(object):
def __init__(self):
self._stack1 = []
self._stack2 = []
def push(self,x):
if len(self._stack1) == 0:
self._stack1.append(x)
elif len(self._stack2) == 0:
self._stack2.append(x)
if len(self._stack2) == 1 and len(self._stack1) >= 1:
while self._stack1:
self._stack2.append(self._stack1.pop(0))
elif len(self._stack1) == 1 and len(self._stack2) > 1:
while self._stack2:
self._stack1.append(self._stack2.pop(0))
def pop(self):
if self._stack1:
return self._stack1.pop(0)
elif self._stack2:
return self._stack2.pop(0)
else:
return None
两个栈实现队列
class QueueWithTwoStacks(object):
def __init__(self):
self._stack1 = []
self._stack2 = []
def appendTail(self,x):
self._stack1.append(x)
def deleteHead(self):
if self._stack2:
return self._stack2.pop()
else:
if self._stack1:
while self._stack1:
self._stack2.append(self._stack1.pop())
return self._stack2.pop()
else:
return None
单向链表 参考
# 首先看单链表
class Chain():
def __init__(self):
self.first = None
self.length = 0
def is_empty(self):
"""是否为空"""
return self.first == None
def add(self, val):
"""头部添加"""
node = Node(val)
temp = self.first
node.next = temp
self.first = node
self.length += 1
def append(self, val):
"""尾部添加"""
node = Node(val)
if self.first:
temp = self.first
mid = None
while temp:
mid = temp
temp = temp.next
mid.next = node
else:
self.first = node
self.length += 1
def __setitem__(self, item, val):
"""插入元素"""
node = Node(val)
temp, index = self.first, 0
if item == 0:
node.next, self.first = self.first, node
self.length += 1
else:
while temp:
if index+1 == item:
node.next, temp.next = temp.next, node
self.length += 1
break
index += 1
temp = temp.next
def __len__(self):
"""链表长度"""
return self.length
@property
def len_2(self):
"""链表长度(时间复杂度O(n))"""
if not self.first:
return 0
else:
temp = self.first
length = 1
while temp.next:
length += 1
temp = temp.next
return length
def pop(self):
"""删除尾部元素(有错误)"""
temp = self.first
mid = None
while temp.next:
mid, temp = temp, temp.next
if mid:
mid.next = None
self.length -= 1
def __delitem__(self, item):
"""删除某一位置元素"""
temp, index = self.first, 0
if item == 0:
if self.first:
self.first = self.first.next
self.length -= 1
while temp:
if index + 1 == item:
temp.next = temp.next.next
self.length -= 1
index += 1
temp = temp.next
def bianli(self):
"""遍历链表"""
temp = self.first
while temp:
print(temp.value)
temp = temp.next
def reverse1(self):
"""反转链表"""
temp = self.first
prev = None
while temp:
temp_next = temp.next
temp.next = prev
prev = temp
temp = temp_next
self.first = prev
def reverse2(self):
"""反转链表"""
chain_list = []
temp = self.first
while temp:
chain_list.append(temp.value)
temp = temp.next
temp = self.first
while temp:
temp.val = chain_list.pop()
temp = temp.next
def __iter__(self):
pass
def __next__(self):
pass
class Node():
def __init__(self, val):
self.value = val
self.next = None
双向链表
# 在来看双向链表
class Node():
def __init__(self, val):
self.value = val
self.prev = None
self.next = None
class Chain():
def __init__(self):
self.first = None
def is_empty(self):
"""是否为空"""
return self.first == None
def add(self, val):
"""头部添加"""
node = Node(val)
self.first.prev = node
temp = self.first
node.next = temp
self.first = node
def append(self, val):
"""尾部添加"""
node = Node(val)
temp = self.first
if not temp:
self.first = node
else:
while temp.next:
temp = temp.next
node.prev = temp
temp.next = node
def __delitem__(self, item):
"""删除元素"""
temp, index = self.first, 0
while temp:
if index == item:
if temp.next:
temp.next.prev, temp.prev.next = temp.prev, temp.next
else:
temp.prev.next = None
index += 1
temp = temp.next
def travel(self):
"""遍历元素"""
temp = self.first
while temp:
print(temp.value)
temp = temp.next