• 数据结构与算法基础


    翻书问题或者走台阶问题

    共有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)
  • 相关阅读:
    DP——斜率优化
    题解报告——数三角形
    题解报告——货车运输
    题解报告——油滴扩展
    题解报告——程序补丁
    题解报告——奖励关
    用bitset解决背包问题
    题解报告——矩阵操作
    题解报告——数列
    题解报告——窗口的星星
  • 原文地址:https://www.cnblogs.com/lz0504/p/9340428.html
Copyright © 2020-2023  润新知