翻书问题或者走台阶问题:
共有n个台阶,每次只能上1个台阶或者2个台阶,共有多少种方法爬完台阶。
共有n页书,每次只能翻1页或者2页书,共有多少种方法翻完全书。
1 # f(n)为翻完全书的方法 2 # 递归写法 3 def f(n): 4 if n == 1: 5 return 1 6 if n == 2: 7 return 2 8 if n > 2: 9 return f(n - 1) + f(n - 2) 10 11 # 迭代写法,或者叫循环写法 12 def f(n): 13 res = [0 for i in range(n + 1)] 14 res[1] = 1 15 res[2] = 2 16 for i in range(3, n+1): 17 res[i] = res[i - 1] + res[i - 2] 18 return res[n] 19 20 21 # 使用缓存 22 cache = {} 23 def fib(n): 24 if n not in cache.keys(): 25 cache[n] = _fib(n) 26 return cache[n] 27 28 def _fib(n): 29 if n == 1 or n == 2: 30 return n 31 else: 32 return fib(n-1) + fib(n-2)
二分查找
1 def LinearSearch(array, t): 2 for i in range(len(array)): 3 if array[i] == t: 4 return True 5 return False 6 7 8 def BinarySearch(array, t): 9 left = 0 10 right = len(array) - 1 11 while left <= right: 12 mid = int((left + right) / 2) 13 if array[mid] < t: 14 left = mid + 1 15 elif array[mid] > t: 16 right = mid - 1 17 else: 18 return True 19 return False 20 21 22 array = list(range(100000000)) 23 24 25 import time 26 27 t1 = time.time() 28 LinearSearch(array, 100000001) 29 t2 = time.time() 30 print('线性查找:', t2 - t1) 31 32 t3 = time.time() 33 BinarySearch(array, 100000001) 34 t4 = time.time() 35 print('二分查找:', t4 - t3)
二分查找例题(变种)
题意
1 2 [ 3 [1, 3, 5, 7], 4 [10, 11, 16, 20], 5 [23, 30, 34, 50] 6 ] 7 8 查找比如16在不在矩阵中。
解法
1 class Solution: 2 # @param matrix, a list of lists of integers 3 # @param target, an integer 4 # @return a boolean 5 def searchMatrix(self, matrix, target): 6 i = 0 7 j = len(matrix[0]) - 1 8 while i < len(matrix) and j >= 0: 9 if matrix[i][j] == target: 10 return True 11 elif matrix[i][j] > target: 12 j -= 1 13 else: 14 i += 1 15 return False
链表
链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。
python代码
1 # 链表中的节点的数据结构 2 class ListNode(object): 3 def __init__(self, x): 4 self.val = x 5 self.next = None 6 7 # 实例化 8 A = ListNode('a') 9 B = ListNode('b') 10 C = ListNode('c') 11 A.next = B 12 B.next = C 13 14 # 这样,一条链表就形成了。 15 # 'a' -> 'b' -> 'c' 16 17 # 遍历链表 18 tmp = A 19 while tmp != None: 20 print(tmp.val) 21 tmp = tmp.next 22 23 # 递归遍历链表 24 def listorder(head): 25 if head: 26 print(head.val) 27 listorder(head.next) 28 29 listorder(A)
例题
翻转一条单向链表。
例子:
1 Input: 1->2->3->4->5->NULL 2 Output: 5->4->3->2->1->NULL
解答:
1 # Definition for singly-linked list. 2 class ListNode(object): 3 def __init__(self, x): 4 self.val = x 5 self.next = None 6 7 class Solution(object): 8 def reverseList(self, head): 9 """ 10 :type head: ListNode 11 :rtype: ListNode 12 """ 13 dummy = head 14 tmp = dummy 15 16 while head and head.next != None: 17 dummy = head.next 18 head.next = dummy.next 19 dummy.next = tmp 20 tmp = dummy 21 return dummy 22 23 head = ListNode(1) 24 head.next = ListNode(2) 25 head.next.next = ListNode(3) 26 head.next.next.next = ListNode(4) 27 head.next.next.next.next = ListNode(5) 28 29 solution = Solution() 30 reverse_head = solution.reverseList(head) 31 tmp = reverse_head 32 while tmp: 33 print(tmp.val) 34 tmp = tmp.next
二叉树
python代码
1 class TreeNode(object): 2 def __init__(self, x): 3 self.val = x 4 self.left = None 5 self.right = None 6 7 root = TreeNode(1) 8 root.left = TreeNode(2) 9 root.right = TreeNode(3) 10 11 ''' 12 1 13 / 14 2 3 15 ''' 16 17 # root就是一颗二叉树
中序遍历(先遍历左子树,再遍历根节点,再遍历右子树)
1 # class TreeNode: 2 # def __init__(self, x): 3 # self.val = x 4 # self.left = None 5 # self.right = None 6 7 def inorder(root): 8 if root: 9 inorder(root.left) 10 print(root.val) 11 inorder(root.right)
前序遍历(先遍历根节点,再遍历左子树,再遍历右子树)
1 class TreeNode: 2 def __init__(self, x): 3 self.val = x 4 self.left = None 5 self.right = None 6 7 def preorder(root): 8 if root: 9 print(root.val) 10 preorder(root.left) 11 preorder(root.right) 12 13 root = TreeNode(1) 14 root.left = TreeNode(2) 15 root.right = TreeNode(3) 16 preorder(root)
后序遍历(先遍历左子树,再遍历右子树,再遍历根节点)
1 # class TreeNode: 2 # def __init__(self, x): 3 # self.val = x 4 # self.left = None 5 # self.right = None 6 7 def postorder(root): 8 if root: 9 postorder(root.left) 10 postorder(root.right) 11 print(root.val)
测试程序
1 class TreeNode: 2 def __init__(self, x): 3 self.val = x 4 self.left = None 5 self.right = None 6 7 def preorder(root): 8 if root: 9 print(root.val) 10 preorder(root.left) 11 preorder(root.right) 12 13 def inorder(root): 14 if root: 15 inorder(root.left) 16 print(root.val) 17 inorder(root.right) 18 19 def postorder(root): 20 if root: 21 postorder(root.left) 22 postorder(root.right) 23 print(root.val) 24 25 root = TreeNode(1) 26 root.left = TreeNode(2) 27 root.right = TreeNode(3) 28 root.left.left = TreeNode(4) 29 root.left.right = TreeNode(5) 30 root.right.left = TreeNode(6) 31 root.right.right = TreeNode(7) 32 33 preorder(root) 34 inorder(root) 35 postorder(root)
已知一颗二叉树的先序遍历序列为ABCDEFG,中序遍历为CDBAEGF,能否唯一确定一颗二叉树?如果可以,请画出这颗二叉树。
A
/
B E
/
C F
/
D G
先序遍历: ABCDEFG
中序遍历: CDBAEGF
后序遍历: DCBGFEA
使用程序根据二叉树的先序遍历和中序遍历来恢复二叉树。
1 class TreeNode: 2 def __init__(self, x): 3 self.val = x 4 self.left = None 5 self.right = None 6 7 def buildTree(preorder, inorder): 8 if len(preorder) == 0: 9 return None 10 if len(preorder) == 1: 11 return TreeNode(preorder[0]) 12 root = TreeNode(preorder[0]) 13 index = inorder.index(root.val) 14 root.left = buildTree(preorder[1 : index + 1], inorder[0 : index]) 15 root.right = buildTree(preorder[index + 1 : len(preorder)], inorder[index + 1 : len(inorder)]) 16 return root 17 18 preorder_string = 'ABCDEFG' 19 inorder_string = 'CDBAEGF' 20 21 r = buildTree(preorder_string, inorder_string) 22 preorder(r) 23 inorder(r) 24 postorder(r)
栈和队列
栈
python实现
1 class Stack(object): 2 def __init__(self): 3 self.stack = [] 4 def pop(self): 5 if self.is_empty(): 6 return None 7 else: 8 return self.stack.pop() 9 def push(self,val): 10 return self.stack.append(val) 11 def peak(self): 12 if self.is_empty(): 13 return None 14 else: 15 return self.stack[-1] 16 def size(self): 17 return len(self.stack) 18 def is_empty(self): 19 return self.size() == 0 20 21 s = Stack() 22 s.push(1) 23 s.peak() 24 s.is_empty() 25 s.pop()
队列
python实现
1 class Queue(object): 2 def __init__(self): 3 self.queue = [] 4 def enqueue(self,val): 5 self.queue.insert(0,val) 6 def dequeue(self): 7 if self.is_empty(): 8 return None 9 else: 10 return self.queue.pop() 11 def size(self): 12 return len(self.queue) 13 def is_empty(self): 14 return self.size() == 0 15 16 q = Queue() 17 q.enqueue(1) 18 q.is_empty() 19 q.dequeue()
使用队列模拟栈。
1 class StackByQueue(object): 2 def __init__(self): 3 self.stack = Queue() 4 def push(self, val): 5 self.stack.enqueue(val) 6 def pop(self): 7 for i in range(self.stack.size() - 1): 8 value = self.stack.dequeue() 9 self.stack.enqueue(value) 10 return self.stack.dequeue()
使用栈模拟队列
1 class QueueByStack(object): 2 def __init__(self): 3 self.queue1 = Stack() 4 self.queue2 = Stack() 5 def enqueue(self, val): 6 self.queue1.push(val) 7 def dequeue(self): 8 for i in range(self.queue1.size() - 1): 9 value = self.queue1.pop() 10 self.queue2.push(value) 11 res = self.queue1.pop() 12 for i in range(self.queue2.size()): 13 value = self.queue2.pop() 14 self.queue1.push(value) 15 return res
插入排序
1 def insertSort(A): 2 for j in range(1, len(A)): 3 key = A[j] 4 i = j - 1 5 while i >= 0 and A[i] > key: 6 A[i + 1] = A[i] 7 i = i - 1 8 A[i + 1] = key 9 return A 10 11 A = [5, 2, 4, 6, 1, 3] 12 13 print(insertSort(A)) 14 15 function insertSort(A) { 16 for (j = 1; j < A.length; j++) { 17 var key = A[j]; 18 var i = j - 1; 19 while (i >= 0 && A[i] > key) { 20 A[i + 1] = A[i]; 21 i = i - 1; 22 } 23 A[i + 1] = key; 24 } 25 return A; 26 } 27 28 var A = [5, 2, 4, 6, 1, 3]; 29 30 console.log(insertSort(A));
快速排序
1 def partition(A, p, r): 2 x = A[r] 3 i = p - 1 4 for j in range(p, r): 5 if A[j] <= x: 6 i = i + 1 7 A[i], A[j] = A[j], A[i] 8 A[i + 1], A[r] = A[r], A[i + 1] 9 return i + 1 10 11 def quickSort(A, p, r): 12 if p < r: 13 q = partition(A, p, r) 14 quickSort(A, p, q - 1) 15 quickSort(A, q + 1, r) 16 17 A = [2, 8, 7, 1, 3, 5, 6, 4] 18 19 quickSort(A, 0, 7) 20 print(A)
时间复杂度
1 假设快速排序的时间复杂度为f(N) 2 f(N) = 2 * f(N / 2) + O(N) 3 f(N) = 2 * (2 * f(N / 4) + O(N/2)) + O(N) 4 ... 5 f(1) = O(1) 6 所以f(N) = O(NlogN)
在数组元素数量为n的数组里面寻找第k大的数
1 def partition(A, p, r): 2 x = A[r] 3 i = p - 1 4 for j in range(p, r): 5 if A[j] >= x: 6 i = i + 1 7 A[i], A[j] = A[j], A[i] 8 A[i + 1], A[r] = A[r], A[i + 1] 9 return i + 1 10 11 def findKthLargest(A, p, r, k): 12 if p <= r: 13 q = partition(A, p, r) 14 if k - 1 == q: 15 return A[q] 16 elif k - 1 < q: 17 return findKthLargest(A, p, q - 1, k) 18 else: 19 return findKthLargest(A, q + 1, r, k) 20 21 A = [2, 8, 7, 1, 3, 5, 6, 4] 22 23 ret = findKthLargest(A, 0, 7, 8) 24 25 print('ret: ', ret)