算法引入 a + b + c = 1000
且 a^2 + b^2 = c^2,
求出 a, b,c所有组合结果
思想:枚举法,列出所有可能结果
1 2 3 4 5 for a in range (1001 ): for b in range (1001 ): for c in range (1001 ): if a + b + c == 1000 and a**2 + b**2 == c**2 : print (a, b, c)
优化
1 2 3 4 5 for a in range (1001 ): for b in range (1001 ): c = 1000 - a - b if a**2 + b**2 == c**2 : print (a, b, c)
算法衡量 时间复杂度 :程序的执行步骤
大O表示法 :忽略常数项和次要项
最坏时间复杂度: 程序最多执行多少个步骤
常见时间复杂度
注: 为
顺序表
顺序表的两种基本实现方式 顺序表包含表头信息 和元素存储区 两部分
元素存储区扩充 两种扩充策略
每次扩充增加固定数目的存储位置,如每次扩充增加10个元素位置
每次扩充容量加倍,如每次扩充增加1倍存储空间
单链表
节点定义 1 2 3 4 class Node : def __init__ (self, val): self.val = val self.next = None
单链表的定义 1 2 3 class SingleLinkList : def __init__ (self, node=None ): self.header = node
单链表操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 class Node : def __init__ (self, val): self.val = val self.next = None class SingleLinkList : def __init__ (self, node=None ): self.header = node def is_empty (self): return self.header == None def length (self): current = self.header count = 0 while current != None : count += 1 current = current.next return count def travel (self): current = self.header while current != None : print (current.val ) current = current.next def append (self, val): current = self.header if current == None : self.header = Node (val) else : while current.next != None : current = current.next current.next = Node (val) def add (self, val): node = Node (val) if self.header == None : self.header = node else : node.next = self.header self.header = node def insert (self, pos, val): node = Node (val) current = self.header if pos == 0 : node.next = current self.header = node elif pos >= self.length (): self.append (val) else : current_pos = 0 while current_pos != pos - 1 : current_pos += 1 current = current.next node.next = current.next current.next = node def remove (self, val): pre = None current = self.header while current.val != val : pre = current current = current.next if pre == None : self.header = current.next else : pre.next = current.next def search (self, val): current = self.header while current != None : if current.val == val : return True current = current.next return False # 测试数据 s = SingleLinkList () s.append (1 ) s.append (2 ) s.append (3 ) s.add (5 ) s.insert (1 , 100 ) s.remove (2 )print (s.travel ())print (s.search (5 ))
单向循环链表 双向链表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 class Node : def __init__ (self, val ): self.val = val self.next = None self.prev = None class DoubleLinkList : def __init__ (self, node=None ): self.header = node def travel (self ): current = self.header while current != None : print (current.val) current = current.next def append (self, val ): current = self.header node = Node(val) if current == None : self.header = node else : while current.next != None : current = current.next current.next = node node.prev = current def add (self, val ): node = Node(val) if self.header == None : self.header = node else : node.next = self.header self.header = node node.next .prev = node def insert (self, pos, val ): node = Node(val) current = self.header if pos == 0 : node.next = current self.header = node node.next .prev = node elif pos >= self.length(): self.append(val) else : current_pos = 0 while current_pos != pos: current_pos += 1 current = current.next node.next = current node.prev = current.prev current.prev = node current.prev.next = node def remove (self, val ): current = self.header while current != None : if current.val == val: if current.prev is None : if current.next is not None : self.header = current.next current.next .prev = None else : self.header = None elif current.next is None : current.prev.next = None else : current.prev.next = current.next current.next .prev = current.prev current = current.next d = DoubleLinkList() d.append(1 ) d.append(2 ) d.append(3 ) d.insert(0 , 6 ) d.remove(2 ) d.travel()
栈 栈的数据结构实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Stack : def __init__ (self ): self.container = [] def push (self, item ): self.container.append(item) def pop (self ): return self.container.pop() def peek (self ): return self.container[-1 ] def size (self ): return self.size() def is_empty (self ): return not self.container s = Stack() s.push(1 ) s.push(2 )print (s.is_empty())
队列 java
代码实现
python
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Queue : def __init__ (self ): self.container = [] def enQueue (self, val ): self.container.insert(0 , val) def deQueue (self ): return self.container.pop() def isEmpty (self ): return not self.container def size (self ): return len (self.container) q = Queue() q.enQueue(1 )print (q.deQueue())
树
树结构是一种非线性存储结构,存储的是具有“一对多”关系的数据元素的集合。每一个非空树都有且只有一个被称为根的结点
基本概念
(1)节点的度 :一个节点含有的子树的个数称为该节点的度
如A节点的度为2、B节点的度为3
(2)树的度 :一棵树中,最大的节点的度称为树的度
如上面这棵树的度为3
(3)叶子节点 :度为0的节点
如K、F、O、P等都是叶子节点
(4)节点的层次 :从根开始定义起,根为第1层,根的子节点为第2层
上面这颗树一共有5层
(5)树的高度或深度 :树中节点的最大层次
上面这颗树的高度或深度为5
(6)森林 :由m(m>=0)棵互不相交的树的集合称为森林
二叉树 二叉树 :每个节点最多含有两个子树的树称为二叉树
几个性质
(1)在二叉树的第 层上至多有个 结点(i>0)
(2)深度为 的二叉树至多有个 结点
(3)对于任意一棵二叉树,如果其叶结点数为 ,而度数为2的结点总数为 ,则
(4)具有 个结点的满二叉树的深度为
(5)对完全二叉树,若从上至下、从左至右编号,则编号为i的结点,其左孩子编号必为 ,其右孩子编号必为
完全二叉树 设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树
满二叉树
平衡二叉树 当且仅当任何节点的两棵子树的高度差不大于1的二叉树
排序二叉树 从根节点按照编号,从左到右进行编号
2-3-4树 红黑树 B树 霍夫曼树 遍历 前序、中序、后序
依据前序和中序或者前序和后序可以完整的构建出一颗二叉树
前序:A B D C E F
中序:B D A E F C
(1)确定根A
(2)依据中序A所在位置划分左右两颗子树
后序:D B F E C A
中序:B D A E F C
(1)确定根的位置A
(2)依据中序划分左右两颗子树
冒泡 思路分析
比较前后两个数, 如果前面一个数比后面一个数大, 则交换位置。
python
示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 arr = [1 , 100 , 35 , 56 , 72 , 5 , 3 , 2 ]def bubble_sort (arr ): """冒泡排序""" pythonj = (len (arr) - 2 ) while j != 0 : flag = 0 i = 0 while i != j: if arr[i] > arr[i+1 ]: arr[i], arr[i+1 ] = arr[i+1 ], arr[i] flag += 1 i += 1 if arr[i] > arr[i+1 ]: arr[i], arr[i+1 ] = arr[i+1 ], arr[i] flag += 1 if flag == 0 : return j -= 1 bubble_sort(arr)print (arr)
java
版本示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class HelloWorld { public static void main (String[] args) { int [] arr = {1 , 5 , 2 , 7 , 9 }; int len = arr.length; for (int j=len-1 ; j>=2 ; j--){ for (int i=0 ; i<j; i++){ if (arr[i] > arr[i+1 ]){ int temp = arr[i + 1 ]; arr[i+1 ] = arr[i]; arr[i] = temp; } } } for (int i=0 ; i<len; i++){ System.out.println(arr[i]); } } }
选择 思路分析
打擂台算法,每次都找到最大值或最小值, 与数组最后一个元素交换位置。
python
示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 arr = [4 , 100 , 35 , 56 , 72 , 5 , 3 , 1 ]def select (arr ): """选择排序""" j = 0 while j != (len (arr) - 1 ): min_index = j start = j index = j + 1 while index != (len (arr) - 1 ): if arr[min_index] > arr[index]: min_index = index index += 1 if arr[min_index] > arr[index]: min_index = index arr[start], arr[min_index] = arr[min_index], arr[start] j += 1 select(arr)print (arr)
java
代码示例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class HelloWorld { public static void main (String[] args) { int [] arr = {1 , 100 , 2 , 7 , 9 }; int len = arr.length; for (int j=len; j>=2 ; j--){ int maxIndex = 0 ; for (int i=1 ; i<j; i++){ if (arr[i] > arr[maxIndex]){ maxIndex = i; } } if (maxIndex != j-1 ){ int temp = arr[j - 1 ]; arr[j - 1 ] = arr[maxIndex]; arr[maxIndex] = temp; } } for (int i=0 ; i<len; i++){ System.out.println(arr[i]); } } }
插入 示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 arr = [100 , 4 , 35 , 23 , 72 , 5 , 3 , 1 ]def insert_sort (arr ): """插入排序""" index = 1 while index != len (arr): start = index while start != 0 : if arr[start] < arr[start - 1 ]: arr[start], arr[start - 1 ] = arr[start - 1 ], arr[start] start -= 1 index += 1 insert_sort(arr)print (arr)
二分 java
示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package com.cskaoyan;import java.util.Scanner; public class Demo { public static void main(String[] args){ // 给定一个有序的数组 int [] arr = {1 , 4 , 11 , 18 , 19 }; int index = binarySearch(arr, 17 ); System.out.println(index); } // 二分查找算法 public static int binarySearch(int [] arr, int num){ int left = 0 ; int right = arr.length - 1 ; int mid = (left + right) / 2 ; while (true){ if (arr[mid] == num){ return mid; } if (arr[mid] > num){ // 更新表达式 right = mid - 1 ; }else { // 更新表达式 left = mid + 1 ; } mid = (left + right) / 2 ; if (left > right){ // 找不到想要的元素 return -1 ; } } } }
数字累加 计算1到100之和
循环
1 2 3 4 5 6 7 public static int sum (int n) { int sum = 0 ; for (int i=1 ; i<=n; i++){ sum+=i; } return sum; }
其他解法
1 2 3 public static int sum (int n) { return (1 + n) * n / 2 ; }
斐波那契 0 1 1 2 3 5 8 13
求第n个斐波那契数列的值
递归
1 2 3 4 5 6 public static int fio (int n) { if (n <= 2 ){ return n - 1 ; } return fio(n-1 ) + fio(n-2 ); }
循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public static int fio (int n) { if (n <= 2 ){ return n - 1 ; } int first = 0 ; int second = 1 ; for (int i=0 ; i<n-2 ; i++){ int sum = first + second; first = second; second = sum; } return second; }
从上到下打印二叉树 示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class Solution { public List<List<Integer>> levelOrder (TreeNode root) { if (root == null ) return new ArrayList (); List<List<Integer>> arrayList = new ArrayList (); Queue<TreeNode> queue = new LinkedList (); queue.add(root); boolean isOdd = false ; while (!queue.isEmpty()){ int size = queue.size(); LinkedList<Integer> temp = new LinkedList (); for (int i=0 ; i<size; i++){ TreeNode node = queue.poll(); if (isOdd){ temp.addFirst(node.val); }else { temp.addLast(node.val); } if (node.left != null ){ queue.add(node.left); } if (node.right != null ){ queue.add(node.right); } } arrayList.add(temp); isOdd = !isOdd; } return arrayList; } }
从上到下打印二叉树
示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Solution { public List<List<Integer>> levelOrder (TreeNode root) { if (root == null ) return new ArrayList (); List<List<Integer>> listArray = new ArrayList (); Queue<TreeNode> queue = new LinkedList (); queue.add(root); while (!queue.isEmpty()){ int size = queue.size(); ArrayList<Integer> temp = new ArrayList (); for (int i=0 ; i<size; i++){ TreeNode node = queue.poll(); temp.add(node.val); if (node.left != null ){ queue.add(node.left); } if (node.right != null ){ queue.add(node.right); } } listArray.add(temp); } return listArray; } }
示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class Solution { public int [] levelOrder(TreeNode root) { if (root == null ) return new int [0 ]; ArrayList<Integer> arrayList = new ArrayList (); Queue<TreeNode> queue = new LinkedList (); queue.add(root); while (!queue.isEmpty()){ TreeNode node = queue.poll(); arrayList.add(node.val); if (node.left != null ){ queue.add(node.left); } if (node.right != null ){ queue.add(node.right); } } int [] res = new int [arrayList.size()]; int index = 0 ; for (Integer i : arrayList){ res[index++] = i; } return res; } }
只出现一次字符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution { public char firstUniqChar (String s) { HashMap<Character, Integer> hashMap = new HashMap (); for (int i=0 ; i<s.length(); i++){ char c = s.charAt(i); if (!hashMap.containsKey(c)){ hashMap.put(c, 1 ); }else { int val = hashMap.get(c); hashMap.put(c, val+1 ); } } for (int i=0 ; i<s.length(); i++){ char c = s.charAt(i); if (hashMap.get(c) == 1 ){ return c; } } return ' ' ; } }
二维数组 示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public boolean findNumberIn2DArray (int [][] matrix, int target) { int row = matrix.length - 1 ; int column = 0 ; while (row >= 0 && column < matrix[0 ].length){ if (matrix[row][column] == target){ return true ; } if (matrix[row][column] > target){ row--; }else { column++; } } return false ; } }