Skip to content

Commit 2281ea1

Browse files
committed
‘’
1 parent 5b448a2 commit 2281ea1

File tree

50 files changed

+989
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+989
-1
lines changed

learning/0.0.学习须知/023.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
---
2+
title: 打鸡血
3+
date: 2020-07-12
4+
---
5+
6+
今天的文章,不浪,没图。给大家加加油!
7+
8+
<img src="./023/1.jpg" alt="PNG" style="zoom: 33%;" />
9+
10+
回顾过去一年,京东、知乎、美团、微博、去哪儿、滴滴等。爆出裁员的有多少,虽然最终都被官方辟谣。**但是,你们懂的。**
11+
12+
<br/>
13+
14+
互联网寒冬之下,所有公司都勒紧裤腰带过活。那么,对于个体的你,不努力,不学习,想去大厂?凭什么。
15+
16+
<br/>
17+
18+
请大家原谅我说话的直白。2020年就目前来看,对于企业是明显的买方市场(供过于求)。**而且,未来几年应该都是这样**。所以,大部分企业在招聘时,是要在很多优秀的人中去选出一个更优秀的人,而不是在一群普通人中选择一个优秀的人。
19+
20+
<br/>
21+
22+
毕竟,如果你不够格,可能简历都过不了。**而对于应届生,如果不能多维度的获取你的信息。那么出几道难题,在没有更好的替代方案之前,目前是唯一的选择。**
23+
24+
<br/>
25+
26+
所以我最终很直白的告诉这位同学,刷题,你还是得刷。该记的,你还是得记。尤其如果目标本身就是一个好的offer,那更应是如此。
27+
28+
<br/>
29+
30+
但是,**这样的回答其实是不负责任的**。虽然我考虑到给对方一点压力,很直白的回复了他。但如果放开这一切,我们为什么学算法?为什么学数据结构?
31+
32+
<br/>
33+
34+
“面试造火箭,工作拧螺丝” ,工作四五年,别说红黑树,就连普通二叉树基本都没手写过,**我知道很多人都是这个状态**。这种状态正常吗?**正常**。但不写不等于不用。就算真的不用,也不等于不需要知道怎么用。
35+
36+
<br/>
37+
38+
**其实,很多学生学习数据结构是有问题的**。就这位同学而言,至少出现背代码,就是绝对错误的。数据结构的本质,在我看来是去契合一些应用场景,自然而然的产生,而不是死记硬背。
39+
40+
<br/>
41+
42+
比如说红黑树,我们需要知道这是一种常用的平衡二叉树(或者说特殊的平衡二叉树)知道其对于查找, 插入,删除的复杂度都是log(n) --- n 这里是说树中元素的个数。如果你是java栈,你可能还需要知道 hashmap 为什么选用红黑树来实现。要知道红黑树可以在一些非实时任务调度中,可以高效公平的调度任务。要知道其所有的应用,都是围绕着“平衡”二字。这才是数据结构的核心。
43+
44+
<br/>
45+
46+
至于实现的细枝末节,**知道固然好,但没必要去逼着自己记忆**。因为,我们的职业生涯里,绝对不可能出现让你手写红黑树的节点删除的场景。
47+
48+
<br/>
49+
50+
但你需要知道为什么创造/引入它,它有什么特殊的,它满足哪些场景,又不满足哪些场景,不满足的场景又如何替代。这才是对数据结构的良好理解。
51+
52+
<br/>
53+
54+
其实,除了算法,在我看来很多别的知识也是这样。**只是说算法,更容易在面试的时候去展示而已。本身而言,并没有什么特殊的。**
55+
56+
<br/>
57+
58+
比如学习操作系统。那我们为什么学习操作系统?难道是让我们造出来一个操作系统吗?显而易见并不是。学习操作系统是让我们了解为什么会提出OS,如果没有OS又会是什么样子。它怎么样做任务调度,怎么样做进程管理,怎么样对可用的硬件做成抽象,死锁是如何产生的,内存是怎么管理的,文件系统是如何实现的,通信是指谁与谁的通信。不是说应付了考试就算学了,而是带着脑子掌握这个东西的脉络,这才是核心。
59+
60+
<br/>
61+
62+
比如学习数据库原理,不是说让你去造一个数据库。当然你有这本事,那也ok。更多的是去了解数据库是如何来抽象数据管理的,大数据在什么场景下应运而生。学了之后,你会知道关系型数据库只是数据库中的冰山一角。你知道缓存,索引,批处理,中间件之中都是有着数据库的影子。你用 git 你会知道 .git 文件下,其实就用几个很简单的数据结构,就构建了一个数据库的雏形。你知道事务控制,其实最初只是想把事情做正确,你知道 ACID 是在保证什么。你知道数据库的整个设计中,很多时候我们是在性能和正确性中做选择。你知道除了程序员之外,还有 DBA 更加会关注高可用。你不会再觉得读写分离,主从备份多么高大上,因为你知道除了读写分离之外,还有快慢分离,异地多活,**Replication 和 Failover 很多东东**,都是上个世纪就有了完美的理论支撑。
63+
64+
<br/>
65+
66+
比如学习计算机网络,不是说让你去死记硬背几层网络模型,都各自是什么。而是让你知道全球互联网是如何运作的,知道TCP为了保证数据可靠做了多少额外的工作,握手为什么是3次,不是456次。知道滑动窗口并不等于leetcode上的几道题。知道层与层之间是如何划分的。知道在计算机网络的基础下,还有计算机网络安全一大块基石。
67+
68+
<br/>
69+
70+
比如学习编译原理,没人让你死记硬背那些分词算法。而是去知道为什么要划分词法,语法,语义分析。知道为什么很多语言要提出中间代码这个东东。知道编译原理很多东西,其实就是 NLP 的基础,其实就是智能机器人的基础。知道在 ES 的设计中,其实也参考很多编译器的设计。
71+
72+
<br/>
73+
74+
当然,我们很可能不会完美的掌握上面所说的所有。**但我们会在这个过程中,去发现自己的知识盲点,进而刻意提高**。而不是一直陷入“学不会-理解不了-记不住”的死循环。
75+
76+
<br/>
77+
78+
当然,对于要找工作的人,我们可以直接去击打一些面试痛点,更好的兼容社会。**但我们面试过后,总归是要知识落地,这才能体现你的最终价值。**
79+
80+
<br/>
81+
82+
不要说什么“面试造火箭,工作拧螺丝”,拧螺丝的人,只能一直留在位置上拧螺丝。而努力拧螺丝的人,说不定就有机会去造火箭。而那些有造火箭能力的人,他们终究会造上火箭。

learning/0.0.学习须知/023/1.jpg

538 KB
Loading

learning/1.3.字符串系列/307.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
title: 旋转字符串(796)
3+
date: 2020-07-12
4+
---
5+
6+
> 今天是小浩算法 “365刷题计划” 第103天。分享的这道题虽然很简单,但是在笔试或者面试当中,出现的频率却非常高。
7+
8+
## 01、题目示例
9+
10+
> 经典常考类算法题目。
11+
12+
<br/>
13+
14+
| 第796题:旋转字符串 |
15+
| ------------------------------------------------------------ |
16+
| 给定两个字符串, A 和 B。A 的旋转操作就是将 A 最左边的字符移动到最右边。例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' 。如果在若干次旋转操作之后,A 能变成B,那么返回True。 |
17+
18+
**示例 1:**
19+
20+
```
21+
输入: A = 'abcde', B = 'cdeab'
22+
输出: true
23+
```
24+
25+
**示例 2:**
26+
27+
```
28+
输入: A = 'abcde', B = 'abced'
29+
输出: false
30+
```
31+
32+
<br/>
33+
34+
**注意:**A 和 B 长度不超过 100。
35+
36+
<br/>
37+
38+
题意还是很容易理解的,说白了就是每次把前面的元素放到最后面:
39+
40+
<img src="./307/1.jpg" alt="PNG" style="zoom: 67%;" />
41+
42+
## 02、题解分析
43+
44+
> 这道题目看起来简单,但其实很容易出错。
45+
46+
<br/>
47+
48+
这道题目最容易想到的解法,其实就是跟着题意来。每次将旋转后的A和目标串对比:
49+
50+
<img src="./307/2.jpg" alt="PNG" style="zoom: 67%;" />
51+
52+
```java
53+
//java
54+
class Solution {
55+
public boolean rotateString(String A, String B) {
56+
if (A.equals("") && B.equals("")) {
57+
return true;
58+
}
59+
int len = A.length();
60+
for (int i = 0; i < len; i++) {
61+
String first = A.substring(0, 1);
62+
String last = A.substring(1, len);
63+
A = last + first;
64+
if (A.equals(B)) {
65+
return true;
66+
}
67+
}
68+
return false;
69+
}
70+
}
71+
```
72+
73+
但是代码其实并不优雅,我们继续观察一下这个字符串:
74+
75+
<img src="./307/3.jpg" alt="PNG" style="zoom: 80%;" />
76+
77+
无论它怎样旋转,最终的 A + A包含了所有可以通过旋转操作从 A 得到的字符串:
78+
79+
<img src="./307/4.jpg" alt="PNG" style="zoom: 50%;" />
80+
81+
那我们是不是只需要判断 B 是否为 A + A 的子串就可以了:
82+
83+
```java
84+
//java
85+
class Solution {    
86+
public boolean rotateString(String AString B) {        
87+
return A.length() == B.length() && (A + A).contains(B);    
88+
}
89+
}
90+
```
91+
92+
执行结果:
93+
94+
<img src="./307/5.jpg" alt="PNG" style="zoom: 80%;" />
95+
96+
一般面试写的话,基本就是到这个程度。但是大概率面试官这时还会问你一个问题:如何继续进行优化?
97+
98+
<img src="./307/6.gif" alt="PNG" style="zoom: 80%;" />
99+
100+
注意我们上面问题,其实已经转化为了:**判断 B 是否为 A + A 的子串**。那我们就可以引申答出 KMP,SUNDAY,BF 等字符串匹配策略。(当然,这里其实 SUNDAY 并不是特别适合)
101+
102+
<br/>
103+
104+
然后就是用相应的匹配策略,来实现转化后的问题。
105+
106+
<br/>
107+
108+
这里附上一份 KMP 解题代码:
109+
110+
```java
111+
class Solution {
112+
public boolean rotateString(String A, String B) {
113+
int N = A.length();
114+
if (N != B.length()) return false;
115+
if (N == 0) return true;
116+
117+
//Compute shift table
118+
int[] shifts = new int[N+1];
119+
Arrays.fill(shifts, 1);
120+
int left = -1;
121+
for (int right = 0; right < N; ++right) {
122+
while (left >= 0 && (B.charAt(left) != B.charAt(right)))
123+
left -= shifts[left];
124+
shifts[right + 1] = right - left++;
125+
}
126+
127+
//Find match of B in A+A
128+
int matchLen = 0;
129+
for (char c: (A+A).toCharArray()) {
130+
while (matchLen >= 0 && B.charAt(matchLen) != c)
131+
matchLen -= shifts[matchLen];
132+
if (++matchLen == N) return true;
133+
}
134+
135+
return false;
136+
}
137+
}
138+
```
139+
140+
这个有兴趣可以看看,代码是 leetcode 官方的。
141+
142+
<br/>
143+
144+
## 03、算法小知识
145+
146+
> KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。
147+
148+
<img src="./307/7.gif" alt="PNG" style="zoom: 80%;" />
149+
150+
大家有兴趣可以看我之前写的一篇KMP教程:
151+
152+
[KMP(上篇)](1.3.字符串系列/306.md)
5.26 KB
Loading
46.9 KB
Loading
10.6 KB
Loading
88.4 KB
Loading
6.78 KB
Loading
314 KB
Loading
225 KB
Loading

0 commit comments

Comments
 (0)