Long Luo's Life Notes

每一天都是奇迹

晚上在水木社区一篇帖子上看到一篇文章《难忘那夜的秋雨》,写的非常真挚感人,看完深受感动,没想到作者居然是 吴官正 。作为一名农民的儿子,曾经有过同样的感受,我想他能从一个赤贫小子成为常委之一,这种骨气和自强不息的精神内核才是根本吧!

《难忘那夜的秋雨》摘自吴官正退休后写的一本书 《闲来笔潭》 ,于是我按图索骥,去读了这本书里的其他文章,有些文章也很精彩。尤其是第一部分:岁月难忘,让我们得以一窥他的年少成长史。从他的经历中获取力量。

下面摘录几篇《闲来笔潭》里我觉得写的很好的文章:


难忘那夜的秋雨

文 / 吴官正

1950年深秋,我母亲到亲戚家赊了头小猪来养。大约过了不到十天,亲戚家的掌门人来到我家,对母亲说:“我是来看弟弟的,顺便来收你赊的猪崽钱。”

母亲说:“现在确实没钱,等筹到钱一定给您送去。”这位掌门人没有说行还是不行。接着,她指着我家的破屋说:“我的亲戚现在住的都不错,就是你还住牛栏,这么破,这么矮,狗都跳得过去。

晚上,父亲知道了,大发脾气。好像猪崽也听懂了似的,不停地叫。父亲骂母亲没骨气,怨亲戚无情,也恨自己没用,坚决要把小猪送还人家,宁愿饿死,也不低三下四

母亲没办法,要我同她一起在小猪脖子上绑了根绳,牵着赶回亲戚家。

已是凌晨二时许,秋风瑟瑟,细雨绵绵。

我在前面牵着小猪,母亲在后面吆喝。快走到村西两棵大樟树旁时,想到这里曾枪毙过一个恶霸、一个反革命,那个恶霸被步枪打穿了胸脯,血肉模糊;那个反革命被手枪打碎了脑壳,脑浆迸溢。因曾亲眼目睹,感觉十分恐怖。顿时我双腿发软,走不动了,吓得哭了起来。

母亲也难过地哭了,安慰我说:“不要怕,哪里有鬼?就是有鬼,也不会吓我们这样的穷人,我活了四十多岁,受过人的欺侮,没有受过鬼的欺侮!”我心里好像得到了一种从未有过的安慰,又好像吃了一颗壮胆药。

再往前走了约一百米,又看见村里一个被邻村杀死的人放在棺材里,并用砖垒了一个小屋,说是报了仇才能下葬。我又害怕起来,但还是硬着头皮,牵拉着小猪往前走。这家伙不停地叫,好像是为我们壮胆,为我们叫苦,抑或是抨击人情太薄

再往前,要翻过一座山,走二里多长的山路,这时雨下得更大了,身上也湿透了。走在山路上,忽然窜出一只动物,不知是狼是狗,吓得我胆战心惊。母亲说:“不要怕,你是个大孩子了,畜生不会伤害我们。”

快到西北边山脚下时,看到一大片坟墓,大大小小的坟堆,好像大大小小的土馒头。母亲说:“再走一会儿就出山了,有我在,你不要怕。”

我想到母亲可怜,又呜呜地哭起来。

大约又过了半个多小时,终于把小猪送到亲戚家,这时天才蒙蒙亮。掌门人淡淡地说:“把猪关到栏里去,你们吃过早饭回去吧?”

我们全身湿透了,像落汤鸡,一夜折腾得够呛,连水都没喝一口,肚子早饿了。但母亲只轻轻地说了句:“谢谢,我们还要赶回去。”

在往回走的路上,天先是阴森森的,慢慢地亮了些,秋雨袭来,身上不时打寒噤。

回到家里,看到我们可怜的样子,父亲没做声,转过身去,不停用手抹眼泪。母亲赶紧把我的湿衣服换了下来,都是打补丁的旧土布衣服。父亲煮了一锅菜粥,桌上放了一碗咸芥菜,也没放油。父亲说:“哼,人穷盐钵里都会长蛆。”

母亲对我说:“你都十多岁了,家里人多,几亩地又打不到够全年吃的粮食,你爸爸也忙不过来,不要再去读书了,好吗?”

我没做声,放下碗,倒在床上哭。父母心软了,让步了,又说:“是同你商量,你硬要读就去读,反正我们穷。”我爬起来,饿着肚子就往学校跑,母亲把我追了回来。

这天傍晚,乌云密布,秋雨扑面,可晒场上的那棵松树,还是那样刚劲,不管严冬还是酷暑,总是那么挺拔。

吃晚饭时,父亲突然问:“你能读个出息来吗?今后能不能当上小学教师?”我说:“不知道,只要你们允许我读,我会努力的。”这时,母亲发现我发高烧,赶紧烧了一大碗开水,叫我全都喝下去,盖上被子把寒气逼出来。

窗外秋雨仍下个不停。秋风从船板做的墙壁缝中往里面灌,冷飕飕的。看到父母骨瘦如柴,岁月和苦难在脸上刻满了忧愁,我鼻子发酸,眼前一片漆黑。再看自己皮包骨头的手,像鸡爪子,皮肤像那两棵老樟树的皮

有人说:“求人比登天难,人情比纸还薄。” 这虽不是生活的全部,却也道出了世态炎凉。

童年经历的人间苦难,令我对生活在社会底层的人感同身受,格外关注弱势群体的生存状况。我自认为是个有情有义的人,尤其懂得知恩图报


阅读全文 »

By Long Luo

这是 Leetcode 525. 连续数组 的题解。

方法一:暴力

思路与算法:

首先想到的方法是暴力法,遍历数组,计算 \(0\)\(1\) 的数量,如果相等,则更新最大长度 \(\textit{maxLength}\)

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public int findMaxLength(int[] nums) {
if (nums == null || nums.length <= 1) {
return 0;
}

int ans = 0;
int len = nums.length;
for (int i = 0; i < len; i++) {
int zeroCnt = 0;
int oneCnt = 0;
for (int j = i; j < len; j++) {
zeroCnt += nums[j] == 0 ? 1 : 0;
oneCnt += nums[j] == 1 ? 1 : 0;

if (zeroCnt == oneCnt) {
ans = Math.max(ans, 2 * zeroCnt);
}
}
}

return ans;
}

复杂度分析:

  • 时间复杂度:\(O(N^2)\),其中 \(N\) 是数组 \(\textit{nums}\) 的长度。
  • 空间复杂度:\(O(1)\)
阅读全文 »

By Long Luo

Leetcode 29. 两数相除 题目如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
29. 两数相除

给定两个整数,被除数`dividend`和除数`divisor`。将两数相除,要求不使用乘法、除法和`mod`运算符。

返回被除数`dividend`除以除数`divisor`得到的商。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3

示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2

提示:
被除数和除数均为$32$位有符号整数。
除数不为$0$。
假设我们的环境只能存储 $32$ 位有符号整数,其数值范围是 [-2^31, 2^31-1]。本题中,如果除法结果溢出,则返回2^31-1。

方法一:暴力法

思路与算法:

因为题目要求不能使用乘法、除法和mod运算符,那么首先想到的是只能使用加减法了。

因为除法就是看被除数能让多少个除数相加,因为被除数和除数均为 \(32\) 位有符号整数,存在溢出的可能,所以我们首先进行类型转换,转换成 \(\textit{Long}\) 型进行处理。

代码如下所示:

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
public int divide(int dividend, int divisor) {
if (dividend == 0) {
return 0;
}

long dividendLong = dividend;
long divisorLong = divisor;

boolean sign = false;
if (dividendLong < 0 && divisorLong < 0) {
dividendLong = -dividendLong;
divisorLong = -divisorLong;
} else if (dividendLong < 0 && divisorLong > 0) {
sign = true;
dividendLong = -dividendLong;
} else if (dividendLong > 0 && divisorLong < 0) {
sign = true;
divisorLong = -divisorLong;
}

long ans = 0;
while (dividendLong >= divisorLong) {
dividendLong -= divisorLong;
ans++;
}

ans = sign ? -ans : ans;

return ans > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) ans;
}

毫无疑问,超时了!

卡在了这个 -2147483648 1 测试用例上,那么我们针对这些边界值进行处理:

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
public int divide(int dividend, int divisor) {
if (divisor == Integer.MIN_VALUE) {
return dividend == Integer.MIN_VALUE ? 1 : 0;
}

if (dividend == Integer.MIN_VALUE) {
if (divisor == 1) {
return dividend;
} else if (divisor == -1) {
return Integer.MAX_VALUE;
}
} else if (dividend == Integer.MAX_VALUE) {
if (divisor == 1) {
return dividend;
} else if (divisor == -1) {
return -dividend;
}
}

long dividendLong = dividend;
long divisorLong = divisor;

boolean sign = false;
if (dividendLong < 0 && divisorLong < 0) {
dividendLong = -dividendLong;
divisorLong = -divisorLong;
} else if (dividendLong < 0 && divisorLong > 0) {
sign = true;
dividendLong = -dividendLong;
} else if (dividendLong > 0 && divisorLong < 0) {
sign = true;
divisorLong = -divisorLong;
}

long ans = 0;
while (dividendLong >= divisorLong) {
dividendLong -= divisorLong;
ans++;
}

ans = sign ? -ans : ans;

return ans > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) ans;
}

因为针对性处理了,所以上述代码 AC 了!

因为题目规定了“只能存储 \(32\) 位整数”,所以代码中都不能使用任何 \(64\) 位整数。

如果除法结果溢出,那么我们需要返回 \(2^{31}-1\) 作为答案。因此我们可以首先对于溢出或者容易出错的边界情况进行讨论:

  • 当被除数为 \(32\) 位有符号整数的最小值 \(-2^{31}\) 时:
    • 如果除数为 \(1\),那么我们可以直接返回答案 \(-2^{31}\)
    • 如果除数为 \(-1\),那么答案为 \(2^{31}\),产生了溢出。此时我们需要返回 \(2^{31}-1\)
  • 当除数为 \(32\) 位有符号整数的最小值 \(-2^{31}\) 时:
    • 如果被除数同样为 \(-2^{31}\),那么我们可以直接返回答案 \(1\)
    • 对于其余的情况,我们返回答案 \(0\)
  • 当被除数为 \(0\) 时,我们可以直接返回答案 \(0\)
阅读全文 »

By Long Luo

VSCode

Everything

NodeJS

cmake

MikeX

CTex

GNU Octave

Octave 下载地址

Matlab

TexStudio

Qt

Keil

Python

conda

anaconda

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/

https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

https://blog.csdn.net/qq_42681787/article/details/144693871

Python 2.7 及以上版本中,Python 自带了一个名为 ensurepip 的模块,可以用来安装 pip。在命令行中运行以下命令:

python -m ensurepip –upgrade

pip –version

pip install requests

#=====新建python2.7环境

conda create -n my_name python=2.7 # 创建conda环境 source activate my_name # 激活conda环境

#=====python2.7环境安装jupyter notebook

which jupyter # 默认jupyter路径,通常是主conda环境下的

新版的ipython只支持python3.4以上版本,python2.7的jupyter需配置如下版本

pip install ipython==5.5.0 pip install ipykernel==4.8.2 which jupyter # my_name环境下的jupyter

#=====保证my_name环境下的package在python可以引用到 import sys sys.path # 如果没有my_name下site-packages路径,则手动加入 sys.path.append(‘/root/anaconda3/envs/my_name/lib/python2.7/site-packages’) #=====启动jupyter nohup jupyter notebook –no-browser –port=3434 –ip=192.168.1.230 –allow-root –notebook-dir=‘/’

Python

Android

Android Studio

Gradle

Java

语音

Praat

By Long Luo

Leetcode 209. 长度最小的子数组 题目如下:

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
209. 长度最小的子数组

给定一个含有$n$个正整数的数组和一个正整数$\textit{target}$。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回$0$。

示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

示例 2:
输入:target = 4, nums = [1,4,4]
输出:1

示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5

进阶:
如果你已经实现 $O(n)$ 时间复杂度的解法, 请尝试设计一个 $O(n\log n)$ 时间复杂度的解法。

方法一:暴力法

思路与算法:

很容易想到,使用 \(2\) 个循环,枚举 \(\textit{nums}\) 中的每个下标作为子数组的开始下标,对于每个子数组 \(i\),满足 \(i \le x \le j\),使得:

\[ sum=\sum_{x=i}^{j}\textit{nums}[x] \ge $\textit{target} \]

,并更新子数组的最小长度 \(j-i+1\)

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public int minSubArrayLen_bf(int target, int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}

int len = nums.length;
int ans = Integer.MAX_VALUE;
for (int i = 0; i < len; i++) {
int sum = 0;
for (int j = i; j < len; j++) {
sum += nums[j];
if (sum >= target) {
ans = Math.min(ans, j - i + 1);
break;
}
}
}

return ans == Integer.MAX_VALUE ? 0 : ans;
}

复杂度分析:

  • 时间复杂度:\(O(N^2)\),其中 \(N\) 是数组 \(\textit{nums}\) 的长度。
  • 空间复杂度:\(O(1)\)

方法二:双指针 + 滑动窗口

思路与算法:

因为求连续子数组的和大于某个值,那么很容易想到使用滑动窗口,使用双指针 \(left\)\(right\) 表示一个窗口:

  1. \(right\) 向右移增大窗口,直到窗口内的数字和大于等于了 \(target\);
  2. 记录此时的长度,\(left\) 向右移动,开始减少长度,每减少一次,就更新最小长度,直到当前窗口内的数字和 \(< target\),回到第 \(1\) 步。

代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public int minSubArrayLen_sw(int target, int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}

int len = nums.length;
int ans = Integer.MAX_VALUE;
int sum = 0;
int left = 0;
int right = 0;
while (right < len) {
sum += nums[right];
while (sum >= target) {
ans = Math.min(ans, right - left + 1);
sum -= nums[left];
left++;
}

right++;
}

return ans == Integer.MAX_VALUE ? 0 : ans;
}

复杂度分析:

  • 时间复杂度:\(O(N)\),其中 \(N\) 是数组 \(\textit{nums}\) 的长度,指针 \(\textit{start}\)\(\textit{end}\) 最多各移动 \(n\) 次。
  • 空间复杂度:\(O(1)\)
阅读全文 »
0%