- 记录刷题记录相关
- Base Structure
- Algorithm
- LeetCode
- Other
Base Structure
Algorithm
BFS与DFS区别
字符串移动
- 给定一个字符串,这个字符串为号和26个字母的任意组合。现在需要把字符串的号都移动到最左侧,而把字符串中的字母移动到最右侧并保持相对顺序不变,要求时间复杂度和空间复杂度最小。
约瑟夫环
想象 0 到 n-1 个人围成一个圈,每个人中的距离是相等的,试求出第 firstNumber 号对面的人是几号
对于
n个人围成一圈,第i个人对面的人的编号为(i + n/2) % n。这个公式基于的原理是,在一个环中,每个人与对面的人的编号之和都是环的大小的一半。因此,我们可以将i的编号加上n/2,然后对n取模,就可以得到i对面的人的编号。1
2
3public int oppositePerson(int n, int firstNumber) {
return (firstNumber + n / 2) % n;
}
二叉树
1 | A |
二叉树前序遍历
先访问当前节点,然后依次访问当前节点的左子树和右子树。即先根节点,再左子树,最后右子树的顺序。
前序遍历结果:A B D E C F G
1
2
3
4
5
6
7
8public void preOrder(TreeNode treeNode) {
if (Objects.isNull(treeNode)) {
return;
}
log.info((String) treeNode.val);
preOrder(treeNode.left);
preOrder(treeNode.right);
}
二叉树中序遍历
先访问当前节点的左子树,然后访问当前节点,最后访问当前节点的右子树。即先左子树,再根节点,最后右子树的顺序。
中序遍历结果:D B E A F C G
1
2
3
4
5
6
7
8public void inOrder(TreeNode treeNode) {
if (Objects.isNull(treeNode)) {
return;
}
inOrder(treeNode.left);
log.info((String) treeNode.val);
inOrder(treeNode.right);
}
二叉树后序遍历
先访问当前节点的左子树和右子树,然后访问当前节点。即先左子树,再右子树,最后根节点的顺序。
后序遍历结果:D E B F G C A
1
2
3
4
5
6
7
8public void postOrder(TreeNode treeNode) {
if (Objects.isNull(treeNode)) {
return;
}
postOrder(treeNode.left);
postOrder(treeNode.right);
log.info((String) treeNode.val);
}
二叉树层序遍历
从二叉树的根节点开始,按照从上到下、从左到右的顺序,依次遍历二叉树的每一层节点。也就是按照树的深度,从上到下逐层遍历,同一层的节点按照从左到右的顺序访问。
常用的实现方法是使用队列,先将根节点加入队列中,然后从队列中取出节点进行访问,同时将该节点的左子节点和右子节点加入队列中,再重复这个过程直到队列为空。这样就可以实现二叉树的层序遍历。
层序遍历结果: A B C D E F G
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void sequenceOrder(TreeNode treeNode) {
if (treeNode == null) {
return;
}
Queue<TreeNode> queue = new LinkedList<>();
//根节点入队
queue.add(treeNode);
while (!queue.isEmpty()) {
//节点出队
TreeNode node = queue.poll();
log.info((String) node.val);
//节点左子树入队
if (node.left != null) {
queue.add(node.left);
}
//节点右子树入队
if (node.right != null) {
queue.add(node.right);
}
}
}
二分查找
查找比某个数字数大的最小数
1 | /** |
查找比某个数字数小的最大数
1 | /** |
LeetCode
LeetCode 21 合并两个有序链表
LeetCode 77 组合
LeetCode 94 二叉树的中序遍历
LeetCode 102 输出一个二叉树的宽度
LeetCode 121 买卖股票的最佳时机
- 贪心算法
1 | public static int maxProfit(int[] prices) { |
LeetCode 122 买卖股票的最佳时机 II
- 贪心算法
1 | public static int maxProfit(int[] prices) { |
LeetCode 144 二叉树的前序遍历
LeetCode 145 二叉树的后序遍历
LeetCode 165 版本号比较
1 | public int compareVersion(String version1, String version2) { |
LeetCode 179 最大数
- 重点方法:自定义比较器Comparator
1 | public String largestNumber(int[] nums) { |
LeetCode 206 单链表反转
LeetCode 300 最长上升子序列
输入: [10,9,2,5,3,7,101,18]
输出: 4 ,最长的上升子序列是 [2,3,7,101],它的长度是 4。
- DP算法
剑指Offer
剑指offer42
TODO
剑指offer43
TODO
Other
数组中找出最长连续序列
TODO
判断一个输入宇符串(只考虑宇母,不区分大小写)是否是回文串
TODO
从一个字符串中找到第一个不重复的字符,返回它的索引。如果不存在,则返回-1
TODO
100个元素的数组中找出长度为3的出现次数最多的元素
TODO
用代码实现两个数字宇符串相加,不限制长度
TODO
主要是将字符串拆分成char数组,从个位开始相加,满十进一,其中代码需要注意char向 int转换的问题。
LeetCode 上合并 区间的题
TODO
二叉树的最近公共祖先
TODO
有序数组合并
TODO
什么是平衡二叉树、最小堆
TODO
字符串消消乐
TODO
链表如何快速查找到两个相关的值
阿拉伯数字转汉字
思路:将“零一二三四五六七八九”、“十百千万亿”这些结果用到的字符存到数组,然后将阿拉伯数字转字符串,遍历拼接结果。
字符串的全排列
输入:s = “abc”
输出:[“abc”,”acb”,”bac”,”bca”,”cab”,”cba”]
有序列表,找出所有两数之和为10000的组合
可以用 HashMap 来存遍历过的数字,每次遍历时检查下 HashMap 里是否有目标数字,时间复杂度O(n),空间复杂度为O(n)。
用双指针,从列表的两边向中间扫,和小于10000,则左指针右移,和大于10000,则右指针左移,双指针理论上没有使用额外的空间。
链表倒数第N个节点算法
单链表奇数节点移动到最前面
输入:a1->a2->a3->a4->a5
输出:a1->a3->a5->a2->a4
打印文件目录结构树
TODO
扑克牌游戏:给5张牌计算牛牛个数
TODO
(o/1/2) 其实是比较简单的两数之和
无向图:找出孤立节点
TODO
虽然是图,但给的数据格式很简单,找到规则遍历即可
获得最优推荐路径 热力值最大
TODO
是道应用题,考的知识点其实是树、最长路径、动态规划。
在参加笔试的时候因为关于树我没有复习,直接卡在数据处理上,稍微骗了点分就提交了
判断2个单链是否有交叉
TODO
2个栈实现一个队列
TODO
最小覆盖子串
TODO
判断链表是否有环
TODO
Java如何实现一个阻塞队列
TODO
手写HashMap
TODO
质量不同的球体中,最快最少次数找出质量最轻的球
分治法
1 | public int getLightestBall(int[] balls) { |
锦标赛算法
1 | private int compare(int[] array, int start, int end) { |
兔子跳下台阶,一次只能跳2阶台阶或3阶台阶,n个台阶至少要跳几次能跳下去,如果跳不下去返回-1
纯计算
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17private int calculate(int fullSteps) {
int count = fullSteps / 3;
int remainStep = fullSteps - count * 3;
if (remainStep > 0) {
int i = remainStep / 2;
count = count + i;
remainStep = remainStep - i * 2;
if (remainStep > 0) {
return -1;
}
}
return count;
}递归
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public int jump(int n) {
if (n == 2 || n == 3) {
return 1;
} else if (n < 2) {
return -1;
} else {
int twoSteps = jump(n - 2);
int threeSteps = jump(n - 3);
if (twoSteps == -1 && threeSteps == -1) {
return -1;
} else if (twoSteps == -1) {
return threeSteps + 1;
} else if (threeSteps == -1) {
return twoSteps + 1;
} else {
return Math.min(twoSteps, threeSteps) + 1;
}
}
}DP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public int calculate(int fullSteps) {
if (fullSteps < 2) {
return -1; // Impossible to traverse the staircase
}
int[] dp = new int[fullSteps + 1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= fullSteps; i++) {
dp[i] = Integer.MAX_VALUE;
if (i - 2 >= 0) {
dp[i] = Math.min(dp[i], dp[i-2] + 1);
}
if (i - 3 >= 0) {
dp[i] = Math.min(dp[i], dp[i-3] + 1);
}
}
if (dp[fullSteps] == Integer.MAX_VALUE) {
return -1; // Impossible to traverse the staircase
} else {
return dp[fullSteps];
}
}
螺旋打印二维数组
给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
1
日期之差,多少天,需要计算闰月
查找单入口空闲区域
时间限制:1s空间限制:256MB 限定语言:不限
题目描述:
给定一个m x n的矩阵,由若干字符X和O构成,X表示该处已被占据,O表示该处空闲,请找到最大的单入口空闲区域。
解释:
空闲区域是由连通的O组成的区域,位于边界的O可以构成入口,单入口空闲区域即有且只有一个位于边界的O作为入口的由连通的O组成的区域
如果两个元素在水平或垂直方向相邻,则称它们是“连通”的,
输入描述:
第一行输入为两个数字,第一个数宇为行数m,第二个数宇列数n,两个数字以空格分隔,1<=m,n <=200,
剩余各行为矩阵各行元素,元素为X或O,各元素间以空格分隔。
输出描述:
若有唯一符合要求的最大单入口空闲区域,输出三个数字,第一个数宇为入口行坐标(范围为0-行数-1),第二个数
字为入口列坐标(范国为0~列数-1),第三个数宇为区域大小,三个数宇以空格分隔;
若有多个符合要求的最大单入口空闲区域,输出一个数字,代表区域的大小;
若没有,输出NUL。
给定两个字符串string1和Istring2.
string1是一个被加扰的宇符串。string1由小写英文宇母(‘a’‘z’)和数字字符(‘0’‘9’)组成,而加扰宇符串由‘0’‘9’、’af’组成。string1里面可能包含0个或多个加扰子串,剩下可能有0个或多个有效子串,这些有效子串被加扰子串隔开。
string2是一个参考字符串,仅由小写英文字母(‘a’~’z’)组成。
你需要在string1字符串里找到一个有效子串,这个有效子串要同时满足下面两个条件:
(1)这个有效子串里不同字母的数量不超过且最接近于string2里 不同宇母的数量,即小于或等于string2里 不同宇母的数量的同时且最大。
(2)这个有效子串是满足条件(1)里的所有子串(如果有多个的话)里宇典序,最大的一个。
如果没有找到合适条件的子串的话,请输出”Not Found”
快递投放问题
有N个快递站点用字符串标识,某些站点之间有道路连接。
每个站点有一些包裹要运输,每个站点间的包裹不重复,路上有检查站会导致部分货物无法通行,计算哪些货物无法正常投递?
输入描述
第一行输入M N,M个包裹N个道路信息.
后面M行分别输入包裹名、包裹起点、包裹终点
后面N行分别表示两个站点之间不能通过的包裹名。检查站禁止通行的包裹如果有多个以空格分开
检查站禁止通行的包裹如果有名个以空格公开
快递员问题
提供一个数组,数组各项代表一个地址,内容为1或者0,1代表此地有包裹需要快递员配送,0代表此地没有包裹需要配送
每个快递员可以配送指定位置及其左右相邻三个地方,问至少需要多少快递员可以把快递送完
岛屿数量
手写LRU
页面置换?淘汰算法? LRU用基础数据结构的实现思路?