Shell和Sql都是日常工作中经常使用的工具,发现LeetCode还有一些Shell和Sql问题,由于项目中写Shell和Sql不是很多,练习的时候有些题目还稍微遇到了一点困难,记录如下。
Shell
192. Word Frequency
难度:Medium
题目大意:
- 写一个bash脚本计算
word.txt
文件中每个单词出现的频率 - 只存在小写字母单词表,单词只使用一个或是多个空格分割
- 输出频率时候按照降序排列,由于保证单词的频率相互不重复,不用考虑再使用字典序做二次排序
示例输入:1
2the day is sunny the the
the sunny is is
示例输出:1
2
3
4the 4
is 3
sunny 2
day 1
使用sort/uniq计算频率
1 | cat words.txt | tr -s ' ' '\n' | sort | uniq -c | sort -r | awk '{ print $2, $1 }' |
- tr -s : 将空格替换为换行,其中
-s --squeeze-repeats
指明将连续的空格视为一个空格 - sort : 按照字典序排序,为统计频率做准备,因为uniq只能统计连续出现的单词
- uniq -c : 将排序后单词序列中连续出现的重复单词去重,
-c
将重复次数输出 - sort -r : 按照频率降序排列结果
- awk : 将输出结果的第一栏和第二栏调换输出
仅仅使用awk和sort
awk功能非常强大。1
awk '{for(i=1;i<=NF;i++) a[$i]++} END {for(k in a) print k,a[k]}' words.txt | sort -k2 -nr
- awk的对于每一行生效的指令中,对于每一行的每一栏的单词,将他们统计到map中
- awk最后指令,将单词与频率输出
- sort -k2 -nr : 使用第二栏的数据,进行降序排序
194. Transpose File
难度:Medium
题目大意:
- 写一个bash脚本转置
file.txt
给出单词的矩阵 - 单词只使用一个空格分割
示例输入:1
2
3name age
alice 21
ryan 30
示例输出:1
2name alice ryan
age 21 30
awk
还是继续awk大法好,awk其实类似于一个文件处理的编程框架。
awk和sed使用好,比直接写shell和使用各种命令进行管道叠加要效率高并且可读性高。1
2
3
4
5
6
7
8
9
10
11
12
13awk '{
row=NR;
col=NF;
for(i=1;i<=NF;i++) a[NR, i]=$i;
}
END {
for(i=1;i<=col;i++) {
printf("%s", a[1, i]);
for(j=2;j<=row;j++)
printf(" %s", a[j, i]);
print "";
}
}' file.txt
直接将单词矩阵存下来,然后转置输出。
Sql
176. Second Highest Salary
难度:Easy
题目大意:
- 从
Employee
表中选出第二高的薪水记录 - 如果不存在第二高的记录,返回
null
1 | +----+--------+ |
1 | select ifnull( |
使用ifnull
函数进行记录是否为空的判断。
178. Rank Scores
难度:Medium
题目大意:
- 用Sql来为分数分级,对于相同的分数,分为同一级,下一级和前一级别连续编号。
1 | +----+-------+ |
1 | select Score, |
参考他人解法,使用零时表中的两个变量,分别记录分级编号和上一个分数,方便判断是否分数相同。
180. Consecutive Numbers
难度:Medium
题目大意:
- 用Sql选出连续出现三次即以上的数字
1 | +----+-----+ |
1 | select distinct Num as ConsecutiveNums from ( |
参考178的思路,将每条记录按照是否连续进行编号,再把所有有三次连续出现的不重复数字选出。
184. Department Highest Salary
难度:Medium
题目大意:
- 挑选出每个部门最高薪水的记录
1 |
|
解法1:900ms
1 | select d.name as Department, e.Name as Employee, Salary |
比较暴力,有个Employee记录都有一个冗余的子查询。
解法2:600ms
1 | select t3.Name as Department, t2.Name as Employee, t1.Salary as Salary |
先把每个部门的最高薪水一起聚合算出,再全连接表并筛选出部门和薪水都匹配的员工记录。
185. Department Top Three Salaries
难度:Hard
题目大意:
- 在上一题基础上,挑选出每个部门前三高薪水的记录
- 如果少于三条记录,则只显示存在的记录
1 | select t1.Name as Department, t2.Name as Employee, t2.Salary as Salary |
和上一题思路类似,先选出第三高的薪水,再全连接筛选。