继续开始做题,还是做最简单的题,巩固基础~~
题1: 去掉最低工资和最高工资后的工资平均值
题目描述
给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资。
请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/average-salary-excluding-the-minimum-and-maximum-salary
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
这应该是简单中的最简单了
先排序,然后删除一头一尾的数据,最后求平均值
提交代码
class Solution:
def average(self, salary: List[int]) -> float:
salary.sort()
salary.pop(0)
salary.pop(-1)
return mean(salary)
提交情况
似乎不太理想,看看别人的解法
class Solution:
def average(self, salary: List[int]) -> float:
return (sum(salary) - max(salary) - min(salary))/(len(salary)-2)
嗯,,这也是最基础的解法,运行时间能缩短不少
题2:判断路径是否相交
题目描述
给你一个字符串 path,其中 path[i] 的值可以是 ‘N’、‘S’、‘E’ 或者 ‘W’,分别表示向北、向南、向东、向西移动一个单位。
机器人从二维平面上的原点 (0, 0) 处开始出发,按 path 所指示的路径行走。
如果路径在任何位置上出现相交的情况,也就是走到之前已经走过的位置,请返回 True ;否则,返回 False 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-crossing
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
个人还是崇尚暴力解题,先列出每个方向前进一步的坐标,判断坐标集合里面有没有重复值。如何判断了,一维的列表可以用set函数去重,二维的用set直接去重肯定不行,会报错。可以将列表中的列表转为tuple元组,然后再去重,如果坐标集合的长度和去重后的列表长度不相等,则返回True。
提交代码
class Solution:
def isPathCrossing(self, path: str) -> bool:
o = [0,0]
N = [0,1]
S = [0,-1]
E = [1,0]
W = [-1,0]
po = [o]
path = list(path)
for p in path:
o = [o[0] + locals()[p][0], o[1] + locals()[p][1]]
po.append(o)
dic = set([tuple(t) for t in po])
return len(dic) != len(po)
代码我要解释一下,locals()函数是将字符串转为变量名,这也是我通过本题学习到的,以前没用过。记住格式locals()[‘s’],比如你首先定义了一个变量s=1,locals()[‘s’]输出也是1。
提交情况
思考
暴力解法毕竟不是最优解,那么更好的解法是怎样的呢?
博主自从用Python以来,就一直用列表多,还有dataframe和numpy数组也用的比较多,集合用的少,上面的解法也是用的列表来解的,其实本题也可以用集合来解
先看看解法
class Solution:
def isPathCrossing(self, path: str) -> bool:
s = set()
# 初始坐标
coor = (0, 0)
# 加入集合
s.add(coor)
# 遍历path,读取前进方向
for p in path:
if p == 'N':
x, y = 0, 1
elif p == 'S':
x, y = 0, -1
elif p == 'E':
x, y = 1, 0
else:
x, y = -1, 0
# 新的坐标
coor = (coor[0] + x, coor[1] + y)
# 判断坐标是否在集合中
if coor in s:
return True
# 加入集合中
s.add(coor)
return False
首先也的初始化一个空的集合和初始坐标,然后定义步长,每走一步,初始坐标加上对应的步长形成新的坐标,并判断这个坐标在不在已有的集合内,如果有的话,就return True,不管咋样,都把这个坐标加入到坐标集合内。
感觉这个思路和我的解法是一样的,不过效率提高了很多。
不过这种解法在判断是否重复上和我不一样,我改成这种判断条件
class Solution:
def isPathCrossing(self, path: str) -> bool:
o = [0,0]
N = [0,1]
S = [0,-1]
E = [1,0]
W = [-1,0]
po = [o]
path = list(path)
for p in path:
o = [o[0] + locals()[p][0], o[1] + locals()[p][1]]
if o in po:
return True
po.append(o)
return False
也是能提高不小的运行速度呢
看来思路还要提升
题3:山羊拉丁文
题目描述
给定一个由空格分割单词的句子 S。每个单词只包含大写或小写字母。
我们要将句子转换为 “Goat Latin”(一种类似于 猪拉丁文 - Pig Latin 的虚构语言)。
山羊拉丁文的规则如下:
如果单词以元音开头(a, e, i, o, u),在单词后添加"ma"。
例如,单词"apple"变为"applema"。
如果单词以辅音字母开头(即非元音字母),移除第一个字符并将它放到末尾,之后再添加"ma"。
例如,单词"goat"变为"oatgma"。
根据单词在句子中的索引,在单词最后添加与索引相同数量的字母’a’,索引从1开始。
例如,在第一个单词后添加"a",在第二个单词后添加"aa",以此类推。
返回将 S 转换为山羊拉丁文后的句子。
示例 1:
输入: “I speak Goat Latin”
输出: “Imaa peaksmaaa oatGmaaaa atinLmaaaaa”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/goat-latin
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
感觉还算简单
先用split函数分割成单个单词列表,然后按要求添加字符,最后用join函数组合成新的句子
提交代码
class Solution:
def toGoatLatin(self, S: str) -> str:
s = S.split(' ')
y = ['a','e','i','o','u','A','E','I','O','U']
for i in range(len(s)):
if s[i][0] in y:
s[i] = s[i] + 'ma' + 'a'*(i+1)
else:
s[i] = s[i][1:] +s[i][0] + 'ma' + 'a'*(i+1)
return ' '.join(s)
提交情况
效率还可以
题4:打印从1到最大的n位数
题目描述
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
这题在不考虑大数的情况下,感觉很简单的一题
提交代码
class Solution:
def printNumbers(self, n: int) -> List[int]:
return list(range(1,10**n))
提交情况
啥玩意儿,仍然处于下半段?
难道这也还能优化?别说,还真有,什么分治算法、动态规划又来了,这里不做搬运工。
如果考虑大数,这题将相当复杂。目前还没想好怎么解,等有空了再来考虑
今天就这样吧~~