算法刷题模板
二叉树
二叉树深度优先递归
public void preOrder(TreeNode root) { if (root != null) { System.out.print(root.val + " "); preOrder(root.left); //左结点遍历完了就遍历右结点。 preOrder(root.right); } }
二叉树深度优先非递归
public ArrayList preOrder1(TreeNode root) { Stack<TreeNode> stack = new Stack<TreeNode>(); ArrayList alist = new ArrayList(); //用来存放遍历结果 TreeNode p = root; while (p != null || !stack.empty()) { while (p != null) { //这里while语句是一直遍历左结点,直到所有左结点遍历完 alist.add(p.val); stack.push(p); p = p.left; } if (!stack.empty()) { //到哪个结点遍历结束左边结点,就弹出这个这个结点,开始遍历又结点 TreeNode temp = stack.pop(); p = temp.right; } } return alist; }
二叉树广度优先
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) { ArrayList<Integer> resultList = new ArrayList<>(); if (root == null) { return resultList; } Queue<TreeNode> q = new LinkedList<>(); q.add(root); while (!q.isEmpty()) { TreeNode nowNode = q.peek(); q.poll(); resultList.add(nowNode.val); if (nowNode.left != null) { q.add(nowNode.left); } if (nowNode.right != null) { q.add(nowNode.right); } } return resultList; }
二分搜索
模板一
int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + ((right - left) >> 1); if (nums[mid] == target) return mid; else if (nums[mid] > target) { right = mid - 1; } else { left = mid + 1; }
模板二
int left = 0; int right = nums.length - 1; while (left < right) { int mid = left + ((right - left) >> 1); if (nums[mid] == target) return mid; else if (nums[mid] > target) { right = mid; } else { left = mid + 1; }
模板三
int left = 0; int right = nums.length - 1; while (left + 1 < right) { int mid = left + ((right - left) >> 1); if (nums[mid] == target) return mid; else if (nums[mid] > target) { right = mid; } else { left = mid; }
动态规划
状态数组,状态转移方程 dp[i] = dp[i - 1] + dp[i - 2]
一维DP
// 状态数组,状态转移方程 dp[i] = dp[i - 1] + dp[i - 2] public int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; int[] dp = new int[n + 1]; dp[1] = 1; for (int i = 2; i < n + 1; i++){ dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; }
二维DP
// 状态数组,状态转移方程 dp[i][j] = dp[i - 1][j] + dp[i][j - 1] public int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; int[] dp = new int[n + 1]; dp[1] = 1; for (int i = 2; i < n + 1; i++){ dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; }
双指针
双指针不同向
int l = 0, r = height.length - 1; int ans = 0; while (l < r) { // 条件判断 if (height[l] <= height[r]) { ++l; }else { --r; } }
双指针同向,判断链表是否有环
ListNode slow = head; // 慢指针 ListNode fast = head; // 快指针 while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { return true; } }
链表
链表翻转java
ListNode prev = null; ListNode current = head; while(current != null) { ListNode nextTemp = current.next; current.next = prev; // 翻转,中间变量使用 prev = current; current = nextTemp; }