leetcode与python进阶学习总结

每天都做两三道LeetCode算法题,以及进一步看了Imooc网上Python进阶的课程,结合所认知的和长时间的Java的使用,总结了一下新学到的知识、让人眼前一亮的程序写法和较java有区别的地方。

一:
注意时间复杂度和空间复杂度
一般我们更注重时间复杂度,常用空间换时间
比如二分法进行递归,时间复杂度一般是O(log n),k层for循环一般是O(n^k)等

二:
# l1是一个链表型,val是其属性,以下句子意义为如果l1不为空则取l1.val否则取0,节省代码空间,干净利落
x= l1.val if l1 else 0
# 三目运算符    条件为真时的结果 if 条件 else 条件为假时的结果
x = x if (x>y) else y  # 取x,y中较大的数并赋给x

三:
# 正则表达式,可实现快速匹配指定字符
import re
re.search(r'^([+|-]?\d+)', " -14")

四:
# 被惊艳到了:判断是否为回文。不知道如何表达,虽然算法的时间空间复杂度差不多,但是这个太简美了
def isPalindrome(self, x: 'int') -> 'bool':
    return str(x) == str(x)[::-1]
    
五:
# 类似数字转罗马数字这种问题,可用枚举涵盖所有情况采用定义枚举的方法,而不是多次if判断
m = [
        ['', 'M', 'MM', 'MMM'],
        ['', 'C', 'CC', 'CCC', 'DC', 'D', 'CD', 'CCD', 'CCCD', 'MC'],
        ['', 'X', 'XX', 'XXX', 'LX', 'L', 'XL', 'XXL', 'XXXL', 'CX'],
        ['', 'I', 'II', 'III', 'VI', 'V', 'IV', 'IIV', 'IIIV', 'XI']
    ]
# 对于罗马转数字这种问题,找其规律,从左到右,字符代表的值不小于右边则加,否则减
def romanToInt(self, s: 'str') -> 'int':
    a = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}        
    ans=0        
    for i in range(len(s)):            
        if i<len(s)-1 and a[s[i]]<a[s[i+1]]:                
            ans-=a[s[i]]
        else:
            ans+=a[s[i]]
    return ans
    
六:
# 对于一个不定长的输入,不要总是罗列枚举各个情况,适度使用if判断
# 比如nums是一个list,求其中和为0的三个数,不可重复
def threeSum(self, nums: 'List[int]') -> 'List[List[int]]':
    for i in range(len(nums)):
        if i == 0 or nums[i]>nums[i-1]:# 此行即避免重复计算或者第一次执行时为true,总之就是找公共部分少罗列
            省略。。。
            
七:
# 排序之后双指针是一个好思想,比如排序后[0,1,2,3,4]求和为3的,从list[0]+list[4]开始,逐步减少
list=[0,1,2,3,4]
left,right = 0,4
while left < right:
    if list[right] + list[left] > 3:
        right-= 1
    elif list[right] + list[left] < 3:
        left += 1
    else:return [list[left],list[rigth]]
return []

八:
# 列表解析,列表生成式,还可带条件过滤
list=[-1, 0, 1,1]
st = [x+2 for x in list] # st变成[1, 2, 3, 3]的列表
st = [x+2 for x in list if list[x]>0] # st变成[3, 3]的列表

九:
# is 和==的区别,is比较的内存地址,==比较的是内容
# java中String类型:==比较的是地址,equals比较内容,

十:
# 一个.py文件是一个模块,一个带__init.py__的文件夹是一个包,不同模块下函数可以重名,不同包下模块可以重名,同java
from math import pow,sin # 导入Math模块中某几个函数
from math import pow as pppp # 现在调用即使用pppp(2,3)即可,相当于起了别名

十一:
# lambda匿名函数可简化程序,但同时增加了理解成本和某些语句不可实现等劣势,用不用视情况而定

十二:
# 双下划线定义的属性不能被外部访问,但可以通过方法访问,相当于Java中Private
class person(object):
    def __init__(self,name):
        self.name = name
        self.__job = 'student'
    def getJob(self):
        return self.__job
p=person('bob')
print(p.name) # 输出bob
print(p.__job) # error
print(p.getJob()) # 输出student

十三:
# 类属性属于类,不需要实例化就可访问,当然,实例化也可访问,且可动态修改添加等
class person(object):
    address= 'earth'
        ...
print(person.address) # 无创建实例即可访问
p1 = person('bob')
print(p1.address) # 实例化后访问
person.address='china' # 可动态修改,再访问时已经改变值,也可添加
p1.address = 'beijing' #修改实例的类属性时,不会影响其他类属性,官方解释是“当实例属性和类属性重名时,实例属性优先级高”

扫描二维码关注公众号,回复: 5482239 查看本文章

十四:
# 父类与子类是is的关系,如果是子类,则也是父类,比如超类是人,继承类是学生,小明是学生,小明也是人
# 而has关系则是组合关系
# 继承时记得初始化,下一个例子有,记录下来,现在没使用到继承,没有概念,需要时百度

十五:
# 多态:这是动态语言(如Python)和静态语言(如java)最大的区别
# 如果子类和父类中都有同名的方法,调用时先调用子类的,如果没有,向上查找父类,直到找到为止
class person(object):
    def __init__(self,name):
        self.name = name
    def whoAmI(self):
        return "im a person"
class student(person):
    def __init__(self,name,score):
        super(student, self).__init__(name)
        self.score = score
    def whoAmI(self):
        return "im a student"
p = person('tim')
s = student('bob',90)
print(p.whoAmI)    # 输出im a person
print(s.whoAmI)    # 输出im a student

十六:
# map方法是可以写默认值的
words_dict[word] = words_dict.get(word, 0) + 1 # 在words_dict字典中是否有Key为word的条目,如果没有,默认值置0,再加+1,若有则加1

十七:
# python较java不同的是允许多重继承
# 除了isinstance()判断是否为某类型,还可以用Type(),还可用dir()获取所有属性
Type(123) # <type 'int'>

十八:
'''特殊函数(又叫magic function):任何实例都有特殊方法以双下划线开始,双下划线结束,比如__str__(),输出为字符,用于len的__len__()方法,用于比较的__cmp__()方法,__int__()等。自定义一个类时没有这些方法,可自行写上,但记得定义时加下划线'''
s="abcd"
print(s)  # 等价于print(s.__str__())
print()

十九:
# __call__()方法实例变成函数
# 一些概念,装饰器,动态增加函数功能
# 闭包

猜你喜欢

转载自blog.csdn.net/qq_36187544/article/details/88047020