请教我kao代码

Knowledge gives us ways to survive the destruction until the rebirth arrives

0%

背景

笔记为学习青戈大佬 从0开始带你手撸一套SpringBoot+Vue后台管理系统(2022年最新版)所总结笔记,瑞斯拜~

软件安装

项目所使用软件及版本如↓

软件包自取:

链接: https://pan.baidu.com/s/10UEXF10CuMSA8zFNrLBYBw?pwd=rb9d 提取码: rb9d

vue安装

还需要安装vue-cli(==这里和视频版本不一致,有问题检查版本==),教程戳vue-cli(vue脚手架)安装 详细教程

抄作业,步骤如下:

阅读全文 »

前言

暴力递归,用于求解能够将每一个问题划分为多个子问题,且子问题与主体问题类型一致,在运算的过程中不记录子问题的结果,同时为了避免程序的死循环,暴力递归还应当具备明确的终止递归条件。暴力递归是动态规划的基础

汉诺塔问题

问题:打印n层汉诺塔,从左边移动到最右边的全部过程

解题思路如↓

实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package p9.recursion;

/**
* @PackageName:p9.recursion
* @ClassName:Code01_Hanoi
* @Description:暴力递归求解汉诺塔问题
* @author:sliu
* @data 2022/5/24 15:42
*/
public class Code01_Hanoi {
public static void main(String[] args) {
//对于有三根柱,三根棍的汉诺塔问题,打印移动顺序
//i > 0
hanoi(3, "左", "中", "右");
}

private static void hanoi(int i, String start, String other, String end) {
if(i == 1){
System.out.println("Move 1 from" + start + "to" + end);
} else{
//1~i-1从from放到other
hanoi(i - 1, start, end, other);
//i放到最终位置end
System.out.println("Move " + i + " from " + start + "to" + end);
//1~i-1从other放到to,继续递归
hanoi(i - 1, other, start, end);
}

}
}

打印子序列

阅读全文 »

前缀树

基本思路

前缀树用于存储字符串等数据的结构,其插入和删除流程大体如↓:

具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package p7.preTreeAndGreedy;

/**
* @PackageName:p7.preTreeAndGreedy
* @ClassName:PreTree
* @Description:前缀树
* @author:sliu
* @data 2022/5/21 19:51
*/
public class PreTree {
public class preNode{
//p值用于有多少个字符串路径经过当前路径
int pass;
//e值用于记录以当前节点为终止节点的路径有多少条
int end;
preNode[] nexts;

public preNode(){
pass = 0;
end = 0;
//nexts用于记录到0-26对应的字母a-z是否存在
//nexts[0] == null表示没有走向a的路径
//nexts[0] != null表示有走向a的路径,且存储了路径的下一个节点
//next[25] == null表示没有走向z的路径
nexts = new preNode[26];
}
}

//初始化根节点
preNode root = new preNode();

//将所传入字符串插入前缀树中
public void insert(String word){
if(word == null){
return;
}
char[] arr = word.toCharArray();
preNode node = root;
node.pass++;
for (int i = 0; i < arr.length; i++) {

int index = arr[i] - 'a';
if(node.nexts[index] == null){
node.nexts[index] = new preNode();
}
node = node.nexts[index];
node.pass++;
}
//终止节点除p值增加外,e值也增加
node.end++;
}

//查询字符串加入过几次
public int search(String word){
if(word == null){
return 0;
}
preNode node = root;
char[] arr = word.toCharArray();
for (int i = 0; i < arr.length; i++) {
int index = arr[i] - 'a';
if(node.nexts[index] == null){
return 0;
}
node = node.nexts[index];
}
//返回最终节点的e值即为字符串加入次数
return node.end;
}

//有多少个单词是以当前所传入word为前缀的,例如以ab为前缀的是abc、abd等
public int pathNumber(String word){
if(word == null){
return 0;
}
preNode node = root;
char[] arr = word.toCharArray();
for (int i = 0; i < arr.length; i++) {
int index = arr[i] - 'a';
if(node.nexts[index] == null){
return 0;
}
node = node.nexts[index];
}
//返回最后一个字符的p值
return node.pass;
}

//删除所传入字符串的路径
public void delete(String word){
//word不存在时,不进行删除操作
if(word == null || search(word) == 0){
return;
}
char[] arr = word.toCharArray();
preNode node = root;
for (int i = 0; i < arr.length; i++) {
int index = arr[i] - 'a';
if(--node.nexts[index].pass == 0){
//当某个节点的p值为0时,应当直接对后续的全部路径进行剪枝操作
node.nexts[index] = null;
return;
}
}
//终止节点的e值减1
--node.end;
}
}

贪心算法

阅读全文 »

前言

对于图的算法,在图的不同表示结构下(例如邻接表和邻接矩阵)有不同的具体实现方式,但是具体的算法思路是一致的,因而在学习过程中只需要掌握好一种结构下的具体实现,在面对其它结构时,将其结构调整到我们所熟悉的那一种就能够搞定它。

本part中的算法均使用以下图结构实现:

Node节点结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package p6.graph;

import java.util.ArrayList;

public class Node {
//节点的值
public int value;
//节点入度
public int in;
//节点出度
public int out;
//与该节点有边相连接的节点集合(该节点指向的节点,即以该点为起点)
public ArrayList<Node> nexts;
//该节点的边集合,以该节点为起点的边
public ArrayList<Edge> edges;

public Node(int value){
this.value = value;
in = 0;
out = 0;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}

Edge边结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package p6.graph;

public class Edge {
//边的权重
public int weight;

//边的入节点
public Node from;

//边的出节点
public Node to;

public Edge(int weight, Node from, Node to){
this.weight = weight;
this.from = from;
this.to = to;
}
}

Graph图结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package p6.graph;

import java.util.HashMap;
import java.util.HashSet;

public class Graph {
//点集合<节点标号,节点>
public HashMap<Integer, Node> nodes;

//边集合
public HashSet<Edge> edges;

public Graph(){
nodes = new HashMap<>();
edges = new HashSet<>();
}

}

图的遍历

阅读全文 »

二叉树的前、中、后序遍历

二叉树经典问题之一,有关前中后序的遍历,主要通过递归和利用栈两种方式来实现,其中递归实现比较简单,思路如下↓

二叉树的前序遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root != null){
//前序遍历
res.add(root.val);
postorderTraversal(root.left);
//中序遍历
//res.add(root.val);
postorderTraversal(root.right);
//后序遍历
//res.add(root.val);
}
return res;
}
}

借助栈实现三种遍历时,每种遍历下如何出栈入栈又有所区别,分别展开来讲

前序遍历

二叉树的前序遍历

前序遍历下,先让根节点入栈

之后逐步出栈,并判断出栈节点左右孩子是否为空,不为空则入栈

阅读全文 »

常用链表结构

基本的链表结构,例如单向链表、双向链表的使用较为常见,不再介绍

而对于几种集合结构:HashSet、HashMap以及TreeMap

其中HashSet和HashMap均为无序集合,HashSet中仅存储Key信息,而HashMap中则以Key-Value键值对的方式存储。TreeMap同样存储键值对信息,但是对键按照有序进行存储,因而,对于TreeMap中传入的键信息为对象时,应当传入对应的比较器以便于排序,否则会报错

对于链表的回顾主要关注于以下一些常见算法题

反转链表

反转单向链表

反转单向链表-leetcode

反转单向链表-牛客

阅读全文 »

前言

本节详解堆排序和桶排序,堆排序中最关键的就是熟悉堆结构的构建和使用

堆结构&堆排序

算法思路

堆结构在逻辑上是一颗完全二叉树, 对于一颗完全二叉树。每一颗子树根节点为最大值,则该完全二叉树为大根堆。相反,每一颗子树其根节点为最小值,则为小根堆

以大根堆下的堆排序为例,排序算法思路如下:

代码实现

大顶堆下的堆排序代码实现:

阅读全文 »

前言

Boom LeetCode(一)中介绍了常用排序算法选择排序、冒泡排序和插入排序,这些排序算法的时间复杂度均为,排序效率较低,而对于排序,结合二分法和归并思想能够有效提升算法查询效率,本部分中介绍时间复杂度的排序算法。

归并排序

算法思路

归并排序通过递归地划分左右数组,对左右数组完成排序后,再合并两个数组,完成最终数组的排序,算法思路如下:

代码实现

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package p2.sort_nlogn;

import java.util.Scanner;

//归并排序
public class MergeSort {

//处理输入输出
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入排序数字个数==========>");
int n = sc.nextInt();
int[] nums = new int[n];
System.out.println("请输入数据============>");
for (int i = 0; i < n; i++) {
nums[i]= sc.nextInt();
}
mergeSort(nums);
for (int num : nums) {
System.out.print(num + " ");
}
}

//调用函数
private static void mergeSort(int[] nums) {
if(nums == null || nums.length < 2){
return;
}
sort(nums, 0, nums.length - 1);
}

//归并排序核心代码
private static void sort(int[] nums, int l, int r) {
if(l == r){
return;
}
int m = l + (r - l) / 2; //int m = l + ((r - l) >> 1);
sort(nums, l , m);
sort(nums, m+1, r);
merge(nums, l, m, r);
}

// 借助辅助数组完成左右数组合并
private static void merge(int[] nums, int l, int m, int r) {
int[] arr = new int[r - l + 1];
int index = 0;
int i = l;
int j = m + 1;
while(i <= m && j <= r){
arr[index++] = nums[i] <= nums[j] ? nums[i++]:nums[j++];
}
while(i <= m){
arr[index++] = nums[i++];
}
while(j <= r){
arr[index++] = nums[j++];
}
for (int k = 0; k < arr.length; k++) {
nums[l + k] = arr[k];
}
}


}

master公式计算其时间复杂度为

阅读全文 »

前言

BoomLeetCode系列笔记为学习左神视频一周刷爆LeetCode所总结笔记,一共38p,计划每天刷1p,笔记更新进度会比较慢

瑞思拜左神~

文章时间复杂度均按最坏情况下计算

时间复杂度

这部分对于有编程基础的来说不是问题,大体上快速过一遍,先以选择排序中的计算方式给出时间复杂度概念

全部笔记已上传github:

简单排序算法

阅读全文 »

前言

本部分所涉及到的分布式系统理论和RPC的概念这块较干,尽量以通熟易懂的例子为引子展开表述。便于理解~

分布式系统理论

分布式可以理解通过多个计算性能弱的服务器来完成计算资源需求大的计算任务

分布式和集群的概念很容易混淆

弹幕看到一个浅显易懂的例子可以帮助理解什么是分布式↓

小饭店原来只有一个厨师,切菜洗菜备料炒菜全干。后来客人多了,厨房一个厨师忙不过来,又请了个厨师,两个厨师都能炒一样的菜,这两个厨师的关系是集群

为了让厨师专心炒菜,把菜做到极致,又请了个配菜师负责切菜,备菜,备料,厨师和配菜师的关系是分布式,一个配菜师也忙不过来了,又请了个配菜师,两个配菜师关系是集群

简单理解,分布式是一个系统,而集群是一个模块

分布式系统概念:建立在网络上的软件系统。由一组通过网络进行通信,为了完成共同的任务而协调工作的计算机节点组成的系统,利用廉价、普通机器完成单个计算机无法完成的计算存储任务。其目的是利用更多的机器,处理更多的数据。

阅读全文 »