数据结构与算法基础

翻书问题或者走台阶问题

共有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)

 

转载于:https://www.cnblogs.com/lz0504/p/9340428.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值