07 2020 档案
摘要:回溯解法 JAVA: public final List<Integer> splitIntoFibonacci(String S) { List<Integer> reList = new LinkedList<Integer>(); search(S, 0, reList, 0); return
阅读全文
摘要:回溯题目,JAVA 实现: public final String[] permutation(String S) { Set<String> reSet = new HashSet<String>(); permutation(S.toCharArray(), new StringBuilder(
阅读全文
摘要:回溯解法,java: public final List<List<String>> partition(String s) { List<List<String>> reList = new LinkedList<List<String>>(); partition(s, 0, new Stack
阅读全文
摘要:动态规划的核心是找到解题路径中的重复子问题,避免重复计算。 找出问题间的递归关系,用问题解决问题需要培养归纳的思维。 问题定义的好坏直接影响到可以定位出的重叠子问题的多少,可以找出的重叠子问题越多,问题定义越好。 下面是两种问题的定义,效率差距非常大。 解法1,超时: public final in
阅读全文
摘要:这次不以面试背题为目的,挑几个源码实现中值得玩味的点来分析一下。 首先看几个初始化参数,在实现中 Lea 大爷大量的使用了二进制位移运算。比如 16 表示为 1<<4 ,1 073 741 824 表示为 1<<30 。由于计算机的物理特性,二进制运算的效率尤其是位移运算是高于直接使用十进制运算的。
阅读全文
摘要:public List<List<String>> solveNQueens(int n) { //棋盘 char[][] board = new char[n][n]; //结果集合 List<List<String>> reList = new LinkedList<List<String>>(
阅读全文
摘要:JS 是单线程的。 JS 是一门解释型脚本语言,主要用于处理浏览器与用户的交互。 个人认为设计为单线程的考量在于: 1、绝大多数交互相关的任务都是 CPU 密集型的短任务,任务耗时短、CPU 占用率高。若使用多线程,线程调度开销占总开销的百分比过大,收益不高。 2、要频繁的处理 DOM 元素。在所有
阅读全文
摘要:缓存分治: public final double largestSumOfAverages(int[] A, int K) { int len = A.length; double re = largest(A, K, 0, len - 1, new double[len][len][K + 1]
阅读全文
摘要:在二维平面上进行回溯搜索: String word; char[][] board; public final boolean exist(char[][] board, String word) { this.word = word; this.board = board; for (int i
阅读全文
摘要:比较常规的解法为回溯解法: List<List<Integer>> reList = new LinkedList<List<Integer>>(); public final List<List<Integer>> subsets1(int[] nums) { reList.add(new Arr
阅读全文
摘要:题目被 leetcode 归类为动态规划,苦思冥想,没有找到合适的问题定义。 决定首先穷举,借以理解解空间的结构。穷举解法: /** * @Author Niuxy * @Date 2020/7/20 11:17 下午 * @Description 穷举 */ String longestStr =
阅读全文
摘要:借助链表实现: class BSTIterator { final List<TreeNode> treeList; int currentPoint; int length; public BSTIterator(TreeNode root) { treeList = new LinkedList
阅读全文
摘要:翻译一下这个题:在固定的集合内寻找符合条件的组合,设组合中相邻的两个元素分别为 pre[],current[] ,则组合需要: 1. 两段视频拼接是没有空隙,也就是 current[0] <= pre[1] 2. 不要重复组合,需要:current[1] > pre[1] 3. 组合要涵盖 0 到
阅读全文
摘要:BFS 解法: private final void addRow(Stack<TreeNode> stack, int v) { while (!stack.empty()) { TreeNode node = stack.pop(); TreeNode newNodeLeft = new Tre
阅读全文
摘要:基于双向数组实现: class MyCircularDeque { class Node { int val; Node pre; Node next; Node(int val) { this.val = val; } } private final int capacity; private f
阅读全文
摘要:首先,既然是缓存,哈希表是必须用到的,保证以 O(1) 时间复杂度进行查询。 另外需要维护元素的使用顺序,不断将近期使用的元素推向前方,并在超出容量时删除末尾元素,这里使用双向链表实现对使用顺序的维护。 class LRUCache { class ListNode { ListNode pre;
阅读全文
摘要:最简单的思路为双递归,内部递归函数用于计算以 node 节点为头元素的路径和, 外部递归函数用于遍历所有节点。 即遍历以每个节点为头元素的所有符合条件的路径: /** * @Author Niuxy * @Date 2020/7/15 11:04 下午 * @Description 双递归 */ p
阅读全文
摘要:public boolean isBalanced(TreeNode root) { if (root == null) { return true; } int diff = getDepth(root.left) - getDepth(root.right); diff = diff > 0 ?
阅读全文
摘要:回溯解法: int an = 0; public final int getMaximumGold(int[][] grid) { for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { g
阅读全文
摘要:一道中规中矩的 DP 题目,但因为问题空间较大,需要做一些优化。 分治法: int an = 0; public final int longestSubsequence(int[] arr, int difference) { if (arr.length == 0) { return 0; }
阅读全文
摘要:这道题怎么说呢,真的很卧槽。分分钟想把出题人打一顿,题目根本没说明白,字符串中会包含 '0' 。状态转移五分钟,边界处理两小时。 DP 解法: public final int numDecodings(String s) { if (s == null || s.length() == 0 ||
阅读全文
摘要:DFS 解法,通过回溯一个 StringBuilder 记录下所有路径代表的数字并求和: StringBuilder sb = new StringBuilder(); int re = 0; public int sumNumbers(TreeNode root) { if (root == nu
阅读全文
摘要:双指针解法1: public final boolean isPalindrome(String s) { int length = s.length(); int leftPoint = 0; int rightPoint = length - 1; s = s.replaceAll("[\\pP
阅读全文
摘要:回溯算法,加缓存过滤已走过的无效路径: public final List<List<Integer>> pathWithObstacles(int[][] obstacleGrid) { Stack<List<Integer>> stack = new Stack<List<Integer>>()
阅读全文
摘要:一个变种的斐波那契数列,DP 没跑了,问题在于如何处理外观的逻辑。用栈存储当前计数的元素,递归表示: public final String countAndSay0(int n) { String[] cache = new String[n + 1]; return countAndSay0(n
阅读全文
摘要:回溯搜索: /** * @Author Niuxy * @Date 2020/7/12 6:41 下午 * @Description 回溯法, 暴力搜索 */ public int minSwap0(int[] A, int[] B) { if (A.length == 0) { return 0;
阅读全文
摘要:当一个问题用递推不好描述时,将目光从整体放到局部,用递归描述对于每个元素我们需要做什么。 问题:text 从 point1 、text2 从 point2 开始的最长公共子序列为 n ,具有递归结构,并存在大量重复子问题。 分治: public final int longestCommonSubs
阅读全文
摘要:暴力解法很容易: /** * @Author Niuxy * @Date 2020/7/9 9:49 下午 * @Description 暴力解法 */ public final int maxArea0(int[] height) { int max = 0; for (int i = 0; i
阅读全文
摘要:暴力解法: public final int maximumSum1(int[] arr) { int max = Integer.MIN_VALUE; for (int i = 0; i < arr.length; i++) { for (int j = i; j < arr.length; j+
阅读全文
摘要:分治解法: public final int lengthOfLIS(int[] nums) { int[] cache = new int[nums.length]; int re = 0; for (int i = 0; i < nums.length; i++) { re = Math.max
阅读全文
摘要:定义 G(b,e) 为 b 到 e 之间的元素可以组成的所有二叉搜索树。 在 b ,e 之间选出一个元素作为根节点, 则以该元素为根的所有可能的二叉搜索树为 G(b,i-1) ,G(i+1,e) 的笛卡尔积。 寻找顶层问题本身的递归结构,走的弯路最少。 public final List<TreeN
阅读全文
摘要:public final boolean isSubPath(ListNode head, TreeNode root) { if (root == null) { return false; } Stack<TreeNode> stack = new Stack<TreeNode>(); stac
阅读全文
摘要:两个关键点,一是在滑动窗口内查找元素, 二是在区间内查找元素。 滑动窗口内查找元素可以使用哈希表维护滑动窗口,保持 O(1) 的查询效率。 区间内查找元素可以使用有序的数据结构,查找出与元素相邻的前后两个元素,判断他们是否在区间内。 /** * @Author Niuxy * @Date 2020/
阅读全文
摘要:巧用数据结构,空间换时间。 /** * @Author Niuxy * @Date 2020/7/4 11:17 下午 * @Description 朴素解法 O(N * min(K,nums.length-N)) */ public boolean containsNearbyDuplicate0
阅读全文
摘要:回溯解法: private List<List<Integer>> anList = new LinkedList<List<Integer>>(); public final List<List<Integer>> combinationSum3(int k, int n) { combinati
阅读全文
摘要:直接挑战 O(1) 空间复杂度解法,双指针尾插法: /** * @Author Niuxy * @Date 2020/7/2 9:16 下午 * @Description 双指针尾插法 */ public void merge(int[] nums1, int m, int[] nums2, int
阅读全文
摘要:暴力求解时找到正确的遍历解空间的方式很重要。有的遍历方式本身具有递归结构,同时存在重复子问题,可以方便的做优化。 寻找函数的定义取决于我们看问题的角度,这与生活中解决问题的思路是相通的。 在剖析问题时,应该从多种角度去观察问题: 从整体到局部、局部到整体的视角转化;关键逻辑的取逆,比如极大化极小、极
阅读全文