前记
写这篇博客的目的是博主觉得自己对python语法不够熟悉。。所以尝试通过leetcode写几道题熟悉一下列表/元组等类型的操作,但是写完感觉算法能力太弱了,写出来的代码不够简洁
一、python的一些基本数据类型
列表
'''
列表:用[]定义,类似于数组;用list()创建
可变的数据类型:append\insert\clear\pop\remove\reverse\opy
'''
lst=['hello','world',98.5,77]
lst1=list("helloworld")
lst2=list(range(1,10,2))
print(lst)
print(lst1)
print(lst2)
print(lst+lst1+lst2)
print(lst*3)
#删除列表
del lst
#列表的遍历:enumerate
lst=['h','hh','hhhh']
for item in lst:print(item)
for i in range(0,len(lst)):print(lst[i])
for index,item in enumerate(lst,start=1): #start表示手动设置序列号print(index,item)
#列表的一些操作
lst.append('sql') #在结尾拼接
lst.insert(1,100) #在1位插入100
lst.remove('h') #删除h
print(lst)
lst.pop(3) #将第三位取出
lst.reverse() #将列表逆序
print(lst)
new_list=lst.copy() #创建新列表
lst.clear() #清空列表
print(new_list+lst)
#列表的排序操作:不会修改地址
lst=[1,2,3,4,5,6,7,8,9]
lst.sort()
print(lst)
lst.sort(reverse=True)
print(lst)lst1=['apple','Orange','banana']
lst1.sort()
print(lst1)
lst1.sort(key=str.lower)#转化成小写进行比较
print(lst1)
#修改地址即产生新列表的排序
nwe_lst=sorted(lst1)
print(lst1)
print(nwe_lst)#列表生成式:lst=[exp for item in range if codition]
import random
del lst
lst=[item for item in range(1,11)]
print(lst)
lst.clear()
lst=[random.randint(1,100) for _ in range(10)]
print(lst)
lst.clear()
lst=[i for i in range(1,10) if i%2==0]
print(lst)
元组
'''
元组:不可变序列,用()创建/用tuple创建
'''
t=('python','hello','world')
lst=['python','hello','world']
#元组支持切片操作
t2=t[0:3:2]
lst2=lst[0:3:2]
print(t2)
print(lst2)#元组生成式:生成了一个生成器对象,需要用tuple转化为元组
del t
t=(i for i in range(1,4))
print(t)
t=tuple(t)
print(t)
字典
'''
字典:可变序列,有点像指针:索引用的键和对应的值构成成对的关系
特点:元组由于不可变,可以作为键,而列表不可以
'''
d={10:'cat',20:'dog',30:'pet',40:'z00'}
lst1=[10,20,30,40]
lst2=['cat','dog','pet','z00']
zipobj=zip(lst1,lst2)
print(zipobj) #映射结果是一个映射对象
for key,value in zipobj:print(key,'---',value)
#print(list(zipobj)) #将映射对象转化为列表类型
othobj=dict(zipobj)
print(othobj)#字典的遍历
d={'hello':10,'world':20,'python':30}
print(d['hello'])
print(d.get('java'))
print(d.get('java','NONE'))for item in d.items():print(item)
for key,value in d.items():print(key,'---',value)
#字典的相关操作
d={1001:'limei',1002:'wanghua',1003:'zhangfeng'}
lst=list(d.items())
print(lst)
print(d)
#字典生成式
import random
d={item:random.randint(1,100) for item in range(4)}
print(d)
lst1=[1001,1002,1003,1004]
lst2=['chen','yiyi','lili']
dd={key:value for key,value in zip(lst1,lst2)}
print(zip(lst1,lst2))
print(dd)
集合
'''
集合类型:可变数据类型,用{}定义,无序不重复序列
'''
#创建集合
s={10,20,30,40}
#只能存储不可变数据类型,比如说列表就不可以作为集合元素
del s
s=set('HELOWORLD')
s1=set([20,23,55])
s2=set(range(1,10))
print(s)
print(s2)
二、题目
解码方法
1.题目描述
2.思路:先将字符串转化为列表,其中字符’0‘必须跟在一个数字后面并且组成的数字<26;接着使用递归,通过10/20对列表进行分组然后将子列表传给counter函数进行计算解码方法总数,counter函数的具体实现:判断传入列表的长度进行对应的操作
3.代码实现
#自己写的。。但是并没有解决问题
#递归-对长字符串而言使用递归时会导致timeout,效率非常低
class Solution:def numDecodings(self, s: str) -> int:ls=list(s)newls=[]i=0#如果以ls[0]==0,应该removeif int(ls[0])==0:return 0#先得到列表,再对列表的字符进行分组while(i<len(ls)):if ls[i]=='0':#newls的最末尾的索引不一定会是i-1newls[len(newls)-1]=int(newls[len(newls)-1]*10)if newls[len(newls)-1]==200 or newls[len(newls)-1]==100:return 0elif ls[i]!='0':newls.append(int(ls[i]))i+=1 print(newls)#如果只有一个数并且为10/20if len(newls)==1 and (newls[0]==10 or newls[0]==20):return 1#递归得到长度 j=0count=1index=0#分为几种情况:中间有10/20且以10/20结尾的;没有10/20;中间有10/20但不以10/20结尾的 while j<len(newls):if newls[j]==10 or newls[j]==20:#以10/20开头的if j==0:count*=1index+=1else:count*=Solution.counter(newls[index:j])index=j+1j+=1if index<j+1:count*=Solution.counter(newls[index:j])return countdef counter(ls:list)->int:if not ls: #传入的列表为空return 0elif len(ls)==1 :return 1#判断并返回if len(ls)==3:v1=int("".join(map(str,ls[0:2])))v2=int("".join(map(str,ls[1:3]))) if v1>26 and v2>26:return 1elif v1<=26 and v2<=26:return 3else:return 2if len(ls)==2:v1=int("".join(map(str,ls[0:2])))if v1<=26:return 2else:return 1if len(ls)==4 :tab=0v1=int("".join(map(str,ls[0:2])))tab+=Solution.counter(ls[1:4])if v1<=26:tab+=(Solution.counter(ls[0:2])*Solution.counter(ls[2:4]))//2return tab#进行分组if len(ls)>4:v1=int("".join(map(str,ls[0:2])))fc=Solution.counter(ls[1:len(ls)])if v1<=26:fc+=Solution.counter(ls[2:len(ls)]) return fc
#转载自评论区,侵权请联系博主删除
#思路:新建cnt列表,然后遍历字符串的每一个字符,记下截止该字符能进行的解码方法数,最后返回末尾的操作数
def numDecodings(s:str) -> int:cnt = [1,1] + [0] * len(s)s = "99" + s #添加虚拟头部,以便不用对头部做特殊处理for i in range(2, len(s)):if( 10 <= int(s[i-1:i+1]) <= 26): #s[i]可与s[i-1]组合cnt[i] += cnt[i-2]if(s[i] != '0'): #s[i]可单独解码cnt[i] += cnt[i-1]return cnt[-1]
合并区间
1.题目描述:以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间
2.思路:递归(二路归并的思想)没解决,但是写着写着对题目的理解就搞混了,所以也并没有实现。
3.代码实现
#!!!!并没有解决题目
class Solution:def devide(intervals:list)->list:result=[]if len(intervals)==1:result.append(intervals[0])return resultif len(intervals)==2:if intervals[0][1]>=intervals[1][0] and intervals[0][0]<=intervals[1][0]:if intervals[0][1]<=intervals[1][1]:result.append([intervals[0][0],intervals[1][1]])return resultelif intervals[0][1]>intervals[1][1]:result.append([intervals[0][0],intervals[0][1]])return resultelif intervals[0][1]>=intervals[1][0] and intervals[0][0]>intervals[1][0]:if intervals[1][0]==intervals[1][1]:result.extend(intervals[1::-1]) #append intervals[1]-intervals[0]return resultif intervals[0][1]<=intervals[1][1]:result.append([intervals[1][0],intervals[1][1]])return resultelif intervals[0][1]>intervals[1][1]:result.append([intervals[1][0],intervals[0][1]])return result return resultelse:result.extend(intervals[0:2])return resultelif len(intervals)==3:item3=[]item3=Solution.devide(intervals[0:2])#如果是两个列表传过去,只会返回两种情况:只剩下一个列表,或者因为其中一个列表的元素 而相同返回两个排好序列表if(len(item3)==1):item33=[item3[0],intervals[2]]item33r=[]item33r.extend(Solution.devide(item33))return item33relif(len(item3)==2):item34=[item3[1],intervals[2]]item34r=[]item34r.append(item3[0])item34r.extend(Solution.devide(item34))return item34relif len(intervals)>3:result.extend(Solution.devide(intervals[0:int(len(intervals)/2)]))result.extend(Solution.devide(intervals[int(len(intervals)/2):len(intervals)]))return resultdef merge(self, intervals: List[List[int]]) -> List[List[int]]:result=Solution.devide(intervals)return result
#来自评论区,侵权请联系博主删除
#思路:使用lambda函数先对intervals这个二维列表进行排序,排序的根据是子列表的第一个数;接着进行合并,合并规则是如果两个区间没有
#重合则在合并列表后append,重叠的话就进行合并
class Solution:def merge(self, intervals: List[List[int]]) -> List[List[int]]:intervals.sort(key=lambda x: x[0])merged = []for interval in intervals:# 如果列表为空,或者当前区间与上一区间不重合,直接添加if not merged or merged[-1][1] < interval[0]:merged.append(interval)else:# 否则的话,我们就可以与上一区间进行合并merged[-1][1] = max(merged[-1][1], interval[1])return merged
4.lambda函数的学习
#lambda函数的使用#-1 一行函数
add=lambda x,y:x+y
result=add(2,3)
print(result)#-2 作为参数传给高阶函数
# map(function,iterable),map的返回值为iterator,如果需要打印需要转化为列表
nums=[1,2,3,4,5]
result2=[item for item in map(lambda x:x**2,nums)]
result22=map(lambda x:x**2,nums)
print(result2)
print(list(result22))#-3 用于排序
nums3=[[9,8,7],[7,6,5],[5,4,3],[3,2,1]]
nums3.sort(key=lambda x:x[0])
#nums3.sort(key=lambda x:x)
#第一种写法根据x[][0]进行排序,第二种写法根据x[]进行排序
print(nums3)
nums33=[[9,8,7],[7,6,5],[5,4,3],[3,2,1]]
nums33.sort(key=lambda x:(x.sort(),x[0]))
print(nums33)
字符串转整数
1.题目描述:请你来实现一个 myAtoi(string s)
函数,使其能将字符串转换成一个 32 位有符号整数(类似 C/C++ 中的 atoi
函数)
2.思路:感觉这题有点咬文嚼字=_=,除去所有不能转化为数字的字符串的情况就可以进行拼接了
3.代码实现
class Solution:def myAtoi(self, s: str) -> int:#空字符串,返回0if s=="":return 0#如果不以数字/空格/+/-开头,均返回0if s[0].isdigit()==False and s[0]!=' ' and s[0]!='+' and s[0]!='-':return 0ss = list(s)i = 0ii = 0
# 先遍历前面不为数字的字符while i < len(ss) and (ss[i] > '9' or ss[i] < '0'):#判断数字前的字符是否均为字母if s[i].isalpha()==True:return 0i += 1if i < len(ss):index=s.find('-',0,i)index1=s.find('+',0,i)#如果同时出现+/-,返回0if index!=-1 and index1!=-1:return 0#如果+/-后面不是数字,返回0if (index1>0 and s[index1+1].isdigit()==False) or (index>0 and s[index+1].isdigit()==False):return 0#如果存在 -if index>=0:while i < len(ss) and ss[i] <= '9' and ss[i] >= '0':ii = ii * 10 + int(ss[i])i += 1ii=0-iielif index<0:while i < len(ss) and ss[i] <= '9' and ss[i] >= '0':ii = ii * 10 + int(ss[i])i += 1if ii>2**31-1:ii=2**31-1elif ii<0-2**31:ii=0-2**31return ii
无重复字符的最长字串
1.题目描述:给定一个字符串 s
,请你找出其中不含有重复字符的最长子串的长度。
2.代码实现
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:ss=""max=0for i in range(len(s)):if s[i] not in ss:ss+=s[i]elif s[i] in ss:if max<len(ss):max=len(ss)#应该向前遍历一遍,将重复字符后的不重复字符加入ss=""tmp=iwhile i-1>=0 and s[tmp-1]!=s[i]:ss+=s[tmp-1]tmp-=1ss=ss[::-1]ss+=s[i]if max<len(ss):max=len(ss)return max
final
总结:学会了列表/元组这类迭代器的一些基本操作,以及lambda函数/map(func,iterable)/append/extend等函数的使用,有时候新建一些数组来存放新内容要比递归高效率。在使用python时多思考方法,因为python有很多意想不到的库函数可以解决复杂问题