Big O notation
O(1): Constant Complexity: Constant 常数复杂度
O(log n): Logarithmic Complexity: 对数复杂度
O(n): Linear Complexity: 线性时间复杂度
O(n^2): N square Complexity: 平方
O(n^3): N square Complexity: 立方
O(2^n): Exponential Growth: 指数
O(n!): Factorial: 阶乘
注意:只看最高复杂度的运算
O(1)
int n = 1000;
System.out.println("Hey - your input is:" + n);
O(N)
for (int i=1; i<=n; i++) {
System.out.println("Hey - I'm busy looking at:" + i);
}
O(N^2)
for (int i=1; i<=n; i++) {
for (int j=1; j<=n; j++) {
System.out.println("Hey - I'm busy looking at:" + i + " and " + j);
}
}
O(log(n))
for (int i=1; i<=n; i=i*2) {
System.out.println("Hey - I'm busy looking at:" + i);
}
O(k^n)
for (int i=1; I<=Math.pow(2,n); i++) {
System.out.println("Hey - I'm busy looking at:" + i);
}
O(n!)
for (int i=1; i<=factorial(n); i++) {
System.out.println("Hey - I'm busy looking at:" + i);
}
常见的算法时间复杂度由小到大一次为:
Ο(1) < Ο(log2n) < Ο(n) < Ο(nlog2n) < Ο(n2) < Ο(n3) < Ο(nk) < Ο(2n)
为了解决大数据下查找 或 搜索的性能问题,通常会使用树的结构来进行管理。下面介绍一下树:
二叉搜索树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted bianary tree),是指一棵空树或者具有下列性质的二叉树:
- 左子树上所有结点的值均小于它的根结点的值;
- 右子树上所有结眯的值均大于它的根结点的值;
- Recursively,左、右子树也分别为二叉查找树。
验证二叉搜索树(BST: Binary Search Tree)
示例1:
- 输入:[3,1,5,null,null,2]
- 输出:true
示例2:
- 输入:[5,1,4,null,null,3,6]
- 输出:false
方式一:时间复杂度O(n)
- 二叉搜索树,中序遍历就是【左、根、右】,得到一个新的数组,就是升序的。这里有个小技巧,就是保存前继节点,如果当前节点比前继节点大的话,就是二叉搜索树。
方式二:时间复杂度O(n)
- 使用递归函数
public boolean validate(TreeNode root, Integer min, Integer max) {
if (root == null) return true;
if (min != null && root.val <= min) return false;
if (max != null && root.val >= max) return false;
return isValid(root.left, min, root.val) &&
isValid(root.right, root.val, max);
}
面试题:二叉树 & 二叉搜索树的最近公共祖先
236.Lowest Common Ancestor of a Binary Tree
TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
return left == null ? right : right == null ? left : root;
}
理论讲解:字典树
- Trie 树的数据结构
- Trie 树的核心思想
- Trie 树的基本性质
Trie 树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索系统用于文本词频统计。
它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
核心思想:
- Trie 的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。
static final int ALPHABET_SIZE = 256;
static class TrieNode {
TrieNode[] children = new TrieNode[ALPHABET_SIZE];
boolean isEndOfWord = false;
TrieNode() {
isEndOfWord = false;
for (int i=0; i< ALPHABET_SIZE; i++)
children[i] = null;
}
};
基本性质:
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
- 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
- 每个节点的所有子节点包含的字符都不相同。
面试题:实现一个字典树(208题)
class TrieNode {
public char val;
public boolean isWord;
public TrieNode[] children = new TrieNode[26];
public TrieNode() {}
TrieNode(char c) {
TrieNode node = new TrieNode();
node.val = c;
}
}