算法训练营总结
发布于: 2021 年 01 月 31 日
内功心法:五毒神掌
数组
不适合插入和删除
链表
LinkedList
常用操作
// 删除
pre.next = curr.next;
// 插入
curr.next = pre.next;
pre.next = curr;
// 反转
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode curr = head;
while(curr != null){
ListNode temp = curr.next;
curr.next = pre;
pre = curr;
curr = temp;
}
return pre;
}
复制代码
跳表
栈
先入后出;添加、删除皆为 O(1)
压栈:push
出栈:pop
查看栈顶元素:peek
队列
先入先出;添加、删除皆为 O(1)
入队(非阻塞):offer
出队(非阻塞):poll
入队(阻塞):put
出队(阻塞):take
查看队头元素:peek
双端队列
优先队列
优先队列 PriorityQueue 是 Queue 接口的实现,可以对其中元素进行排序,PrioritQueue 是一个小根堆
堆排序只能保证根是最大(最小),整个堆并不是有序的
插入操作:O(1)
取出操作:O(logN) - 按照元素的优先级取出
Comparator<Object> cmp = new Comparator<Object>() {
public int compare(Object o1, Object o2) {
//升序
return o1-o2;
//降序
return o2-o1;
}
};
复制代码
哈希表
二叉树
前序(Pre-order):根-左-右
中序(In-order):左-根-右
后序(Post-order):左-右-根
前序遍历
// 递归
public static void preOrderRecur(TreeNode head) {
if (head == null) {
return;
}
System.out.print(head.value + " ");
preOrderRecur(head.left);
preOrderRecur(head.right);
}
// 非递归
public static void preOrderIteration(TreeNode head) {
if (head == null) {
return;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
System.out.print(node.value + " ");
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
}
复制代码
中序遍历
// 递归
public static void preOrderRecur(TreeNode head) {
if (head == null) {
return;
}
preOrderRecur(head.left);
System.out.print(head.value + " ");
preOrderRecur(head.right);
}
// 非递归
public static void inOrderIteration(TreeNode head) {
if (head == null) {
return;
}
TreeNode cur = head;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || cur != null) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
TreeNode node = stack.pop();
System.out.print(node.value + " ");
if (node.right != null) {
cur = node.right;
}
}
}
复制代码
后序遍历
// 递归
public static void postOrderRecur(TreeNode head) {
if (head == null) {
return;
}
postOrderRecur(head.left);
postOrderRecur(head.right);
System.out.print(head.value + " ");
}
// 非递归
// 左右中-->中右左,按中右左的顺序输出到一个栈中,再把栈输出就是左右中
public static void postOrderIteration(TreeNode head) {
if (head == null) {
return;
}
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
stack1.push(head);
while (!stack1.isEmpty()) {
TreeNode node = stack1.pop();
stack2.push(node);
if (node.left != null) {
stack1.push(node.left);
}
if (node.right != null) {
stack1.push(node.right);
}
}
while (!stack2.isEmpty()) {
System.out.print(stack2.pop().value + " ");
}
}
复制代码
颜色标记法
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
WHITE, GRAY = 0, 1
res = []
stack = [(WHITE, root)]
while stack:
color, node = stack.pop()
if node is None: continue
if color == WHITE:
stack.append((WHITE, node.right))
stack.append((GRAY, node))
stack.append((WHITE, node.left))
else:
res.append(node.val)
return res
复制代码
层次遍历
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
if (root == null){
return res;
}
Deque<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()){
int size = queue.size();
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
list.add(node.val);
if (node.left != null){
queue.offer(node.left);
}
if (node.right != null){
queue.offer(node.right);
}
}
res.add(list);
}
return res;
}
复制代码
递归
不要人肉进行递归(最大误区)
2. 找到最近最简方法,将其拆解成可重复解决的问题(重复子问题)
3. 数学归纳法思维
public void recur(int level, int param) {
// terminator
if (level > MAX_LEVEL) {
// process result
return;
}
// process current logic
process(level, param);
// drill down
recur( level: level + 1, newParam);
// restore current status
}
复制代码
分治
def divide_conquer(problem, param1, param2, ...):
# recursion terminator
if problem is None:
print_result
return
# prepare data
data = prepare_data(problem)
subproblems = split_problem(problem, data)
# conquer subproblems
subresult1 = self.divide_conquer(subproblems[0], p1, ...)
subresult2 = self.divide_conquer(subproblems[1], p1, ...)
subresult3 = self.divide_conquer(subproblems[2], p1, ...)
...
# process and generate the final result
result = process_result(subresult1, subresult2, subresult3, …)
# revert the current level states
复制代码
深度优先
visited = set()
def dfs(node, visited):
if node in visited: # terminator
# already visited
return
visited.add(node)
# process current node here.
...
for next_node in node.children():
if not next_node in visited:
dfs(next node, visited)
复制代码
广度优先
def BFS(graph, start, end):
queue = []
queue.append([start])
visited.add(start)
while queue:
node = queue.pop()
visited.add(node)
process(node)
nodes = generate_related_nodes(node)
queue.push(nodes)
复制代码
二分查找
left, right = 0, len(array) - 1
while left <= right:
mid = (left + right) / 2
if array[mid] == target:
# find the target!!
break or return result
elif array[mid] < target:
left = mid + 1
else:
right = mid - 1
复制代码
划线
评论
复制
发布于: 2021 年 01 月 31 日阅读数: 33
Geek_ac4080
关注
还未添加个人签名 2019.05.09 加入
还未添加个人简介
评论