python leetcode1

13. 罗马数字转整数

我也不知道为什么这个可以通过,没细想.
我是采用两个一比对,这样的话需要看一看最后一位取的到吗?

# 首先的想法:
#     1.他已经说明输入一定为正确的罗马数字(字符串形式)
#     2.将六种特殊情况现在字符串中排查一遍,转化成数字,并在字符串中删除
#     3.将其他字符将字符串中转化为数字


def fun1(s):
    #创建一个字典
    dic_liu={
   'IV':4,'IX':9,'XL':40,'XC':90,'CD':400,'CM':900}
    dic_={
   'I':1,'V ':5,'X ':10,'L':50,'C':100,'D':500,'M':1000}

    #用来求和的变量
    sum_=0

    #用来记录当前位置的变量
    i=0
    if len(s)==1:
        return dic_[s]
    while i<len(s)-1:
        key=s[i:i+2:]
        print(key)
        if key in dic_liu.keys():
            sum_+=dic_liu[key]
            if i+2==len(s)-1:
                sum_+=dic_[s[i+2]]
            i+=2
        else:
            sum_+=dic_[key[0]]
            if i+1==len(s)-1:
                sum_+=dic_[s[i+1]]
            i+=1

    return sum_

def fun2(s):
    
    #就是什么样的情况-,什么样的情况+
    dic_={
   
        'I': 1,
        'V': 5,
        'X': 10,
        'L': 50,
        'C': 100,
        'D': 500,
        'M': 1000,
    }

    sum_=0
    n=len(s)
    for i,ch in enumerate(s):
        item=dic_[ch]
        #输入的一定是正确的
        if i<n-1 and item<dic_[s[i+1]]:#这样判断的前提是输入是''正确''的
            sum_-=item
        else:
            sum_+=item
    return sum_

=============================================================================================================================================================================================================================================================================================

14. 最长公共前缀

#首先的想法是每一次将数组中的遍历一遍
#将首位进行比对,如果都一样,在继续比对第二位

def fun1(strs):
    if len(strs)==1:
        return strs[0]
    first=strs[0]
    for i in range(len(first)):#总共遍历数组的次数
        for j in range(1,len(strs)):#把数组走一遍
            if i<len(strs[j]):
                if first[i]!=strs[j][i]:
                    #不相等时进来
                    #假设当前i等于2,后面的代码又是return
                    #说明前面都没有进来过,也就是说first的第0位和第1位与其他元素均一样
                    #这时候i==2在与某个元素判断时却进来了,那么就不可能继续往后面走了
                    return first[0:i:]
            else:
                #i和len(strs[j])只有两种情况小于或等于
                #进来的一定是等于情况
                #能进来说明此时i对应的数字大于等于当前元素的长度,所以
                return first[0:i:]
    return first






#又有了一种想法,先将字符串数组中的第一个和第二个拿出来比对一下
    #1.如果没有共同前缀,则直接输出没有
    #2.如果有公共前缀(假设为flx),那么最长公共前缀长度一定小于等于flx
    #3.通过上述可以减少比对的次数


def fun2(strs):
    if len(strs) == 1:
        return strs[0]
        # 用来记录相同元素
    str = ""
    # 假设一个为abcdffg
    # 一个为abcd
    # 只需要循环到长度最短的末尾就行了
    first = strs[0]
    dier = strs[1]
    i = 0

    while i < len(first) and i < len(dier):
        if first[i] == dier[i]:
            str += first[i]
        else:
            break
        i += 1

    # 得到了他俩的公共前缀
    for i in range(2, len(strs)):
        item = strs[i]
        j = 0
        panduan = ""
        while j < len(item) and j < len(str):
            if str[j] == item[j]:
                panduan += str[j]
            else:
                if panduan == "":
                    return ""
                break
            j += 1
        str = panduan

    return str


#上面两种方法本质上都是暴力枚举



#他可以分解成更小的相似部分进行对比,所以可以使用
#递归
def fun3(strs):
    right=len(strs)-1
    if right==0:
        #说明只有一个元素
        return strs[0]
    mid=right//2
    leftStr,rightStr=fun3(strs[0:mid+1:]),fun3(strs[mid+1::])#这里为了防止有一个list为空所以这样切分
    #返回的结果为字符串,开始两个两个的找公共部分
    i=0
    while i<len(leftStr) and i<len(rightStr):
        if leftStr[i]!=rightStr[i]:
            #这里的问题是当前的i对应的值不相等所以后面就不用看了
            #前面的也没有问题所以直接return(和上面fun1()有点像的对比)
            return leftStr[0:i:]
        i+=1
    #循环结束还没有return的话就将最短的那个输出
    if len(leftStr)<len(rightStr):
        return leftStr
    else:
        return rightStr





if __name__ == '__main__':
    fun3(["flower","flow","flight"])

=============================================================================================================================================================================================================================================================================================

26.删除有序数组中的重复项

#首先给定的是有序的数组
#返回值是不重复元素组成数组的长度
#她会将其输出
#这也就是说,你只需要把重复的挪到后面就行了



#双指针的写法
def fun1(nums):
    #数组为空单独拿出来判断
    if nums==[]:
        return 0
    if len(nums)==1:
        #只有一个元素可以直接输出
        return 1
    quick,slow=1,1
    while quick<len(nums):
        #进行一下判断
        #数组是有序的,相同的元素会一窝一窝的聚集在一起
        #那么当,当前的quick和quick-1对应的元素不同时
        #你就到了另一窝
        if nums[quick]==nums[quick-1]:
            quick+=1
        else:
            nums[slow]=nums[quick]
            slow+=1
            quick+=1
    return slow

=============================================================================================================================================================================================================================================================================================

27. 移除元素

#



#这个好像是双指针优化
def fun1(nums,val):
    right=len(nums)-1
    cur=0
    while cur<=right:
        if nums[cur]!=val:
            #不相等
            cur+=1
        else:
            #相等
            #和right换位置
            nums[right],nums[cur]=nums[cur],nums[right]
            #因为你不知道换位置的那个元素,是否与val的值相等所以需要再进行一次判断
            right-=1
    return cur


#正常的双指针
#就是把应该输出的往前移动
#不应该输出的会随着'''应该输出'''的前移而不断后移
def fun2(nums,val):
    quick=0
    slow=0
    while quick<len(nums):
        if nums[quick]!=val:
            #将其前移
            nums[quick],nums[slow]=nums[slow],nums[quick]
            slow+=1
        quick+=1
    return slow


#其实fun2的代码nums[quick],nums[slow]=nums[slow],nums[quick]是不需要的
#因为你本身slow位置的元素从来都没有通过''slow下标''被比较过
#也就是说无论你那个位置放什么都行

def fun3(nums,val):
    quick=0
    slow=0
    while quick<len(nums):
        if nums[quick]!=val:
            #将其前移
            nums[slow]=nums[quick]
            slow+=1
        quick+=1
    return slow

=============================================================================================================================================================================================================================================================================================

28. 实现 strStr()
这里其实组好是使用KMP,但是我看了半天吐了

注意fun1和fun2都是暴力方法.但fun1逻辑上有些许问题,不够简洁,错误较多
fun2在80个测试点通过了78,后面的数据他大了.
注意fun2中采用双指针时,用 slow+quick.这使得slow不需要移动,只需要移动quick
方便了回溯(当匹配不成功回到原点+1)


def fun1(haystack,needle):
    if len(needle) == 0:
        return 0
    i = 0
    while i < len(needle):
        j = 0
        while j < len(haystack):
            if needle[i] != haystack[j]:
                # 如果是不等于有两种情况
                # 1.他是needle的首位元素:只需要j+1就行了
                # 2.他不是needle的首位元素:你是需要退回来
                if i == 0:
                    j += 1
                else:
                    i = 0
            else:
                if i == len(needle) - 1:
                    return j - i
                j += 1
                i += 1
        # 当你查完了一遍,i还等于0那么肯定是没对应的结果
        if i == 0:
            return -1
    return j - i


def fun2(haystack,needle):
    if len(needle) == 0:
        return 0


    slow=0
    while slow+len(needle)<=len(haystack):#(slow相当于匹配的起点)
        #这个变量使用了记录needle的位置
        quick = 0
        while quick<len(needle):
            #这里使用的是slow+quick所以在这个quick<len(needle)循环中slow始终不需要
            #进行数值的更改
            if needle[quick]==haystack[slow+quick]:
                #继续下一个字符的匹配
                quick+=1
            else:
                slow+=1
                break

        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值