摘要:
维护两个栈,第一个栈支持插入操作,第二个栈支持删除操作。 根据栈先进后出的特性,我们每次往第一个栈里插入元素后,第一个栈的顶部元素是最后插入的元素,第一个栈的底部元素是下一个待删除的元素。 为了维护队列先进先出的特性,我们引入第二个栈,用第二个栈维护待删除的元素,在执行删除操作的时候我们首先看下第二 阅读全文
摘要:
如果一个节点有右子树,那么它的下一个节点就是它的右子树中的最左子节点。 接着我们分析一个节点没有右子树的情形: 如果结点是它父节点的左子节点,那么它的下一个节点就是它的父节点。 如果一个节点没有右子树,并且它还是它父节点的右子节点。我们可以沿着指向父节点的指针一直向上遍历,直到找到一个是它父节点的左 阅读全文
摘要:
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), r 阅读全文
摘要:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solu 阅读全文
摘要:
在部分编程语言中,我们可以动态地将原数组长度扩大,此时我们就可以使用双指针算法,来降低空间的使用: 首先遍历一遍原数组,求出最终答案的长度length; 将原数组resize成length大小; 使用两个指针,指针i指向原字符串的末尾,指针j指向length的位置; 两个指针分别从后往前遍历,如果s 阅读全文
摘要:
由于给定的二维数组具备每行从左到右递增以及每列从上到下递增的特点,当访问到一个元素时,可以排除数组中的部分元素。 从二维数组的右上角开始查找。如果当前元素等于目标值,则返回 true。如果当前元素大于目标值,则移到左边一列。如果当前元素小于目标值,则移到下边一行。 可以证明这种方法不会错过目标值。如 阅读全文
摘要:
二分出重复出现的数。 一共有 n+1 个数,每个数的取值范围是1到n,所以至少会有一个数出现两次。 然后我们采用分治的思想,将每个数的取值的区间[1, n]划分成[1, n/2]和[n/2+1, n]两个子区间,然后分别统计两个区间中数的个数。 注意这里的区间是指 数的取值范围,而不是 数组下标。 阅读全文
摘要:
遍历数组 \(nums\): 若 \(nums[i] = i\) : 说明此数字已在对应索引位置,无需交换,因此跳过; 若 \(nums[nums[i]] = nums[i]\) : 代表索引 \(nums[i]\) 处和索引 \(i\) 处的元素值都为 \(nums[i]\) ,即找到一组重复值, 阅读全文
摘要:
一个数 \(n\) 是 \(2\) 的幂,当且仅当 \(n\) 是正整数,并且 \(n\) 的二进制表示中仅包含 1 个 1。 因此我们可以考虑使用位运算,将 \(n\) 的二进制表示中最低位的那个 \(1\) 提取出来,再判断剩余的数值是否为 \(0\) 即可。下面介绍两种常见的与「二进制表示中最 阅读全文
摘要:
二分图的最大匹配,匈牙利算法裸题。 const int N = 210; vector<int> g[N]; bool vis[N]; int match[N]; int n, m; int find(int x) { for(int i = 0; i < g[x].size(); i++) { i 阅读全文