写点什么

算法训练营总结

用户头像
Geek_ac4080
关注
发布于: 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;    }
复制代码


递归

  1. 不要人肉进行递归(最大误区)

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 terminatorif 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 visitedreturn 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) - 1while 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
复制代码


用户头像

Geek_ac4080

关注

还未添加个人签名 2019.05.09 加入

还未添加个人简介

评论

发布
暂无评论
算法训练营总结