leetcode刷题学习

2019.1.30

9. Palindrome Number

方法1(自己想的比较笨的方法):
将给的数字逆序判断与原来是否一致

class Solution:
    def isPalindrome(self, x):
        if x >= 0:
            b = 0
            y = x
            while y > 0:
                a = y % 10
                b = b*10 + a
                y //=10
            if x == b:
                return True
        return False
            

Runtime: 244 ms, faster than 67.26% of Python3 online submissions for Palindrome Number.

方法2.discussion中的直接将input转化为字符串格式,将字符串逆序。

class Solution:
    def isPalindrome(self, x):
        return str(x) == str(x)[::-1]

Runtime: 228 ms, faster than 99.53% of Python3 online submissions for Palindrome Number.
discussion里面的C,JAVA的runtime基本都是小于100ms的,python的运行速度和基础语言差别好大。

2019.2.17

Roman to Integer

题目要求:将罗马数字字符串转换为整数形式,"I"代表1,"V"代表5,"X"代表10,"L"代表50,"C"代表100,"D"代表500,"M"代表1000。较大数字在前则表示相应数字加和,较小数字在前则代表大数字减小数字。
思路:首先需要把罗马数字所代表的含义以字典的形式储存起来,然后对字符串进行遍历,如果遍历到的字符所代表的数字大于后一个字符所代表的数字,当前整数则加上遍历到的字符所代表的数字;如果遍历到的字符所代表数字小于后一个字符所代表的数字,当前整数则减去遍历到的字符所代表的数字。遍历到倒数第二个字符停止,最终返回停止循环时的整数再加上最后一个字符所对应数字。

class Solution:
    def romanToInt(self, s):
        roman = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
        integer = 0
        for i in range(len(s)-1):
            if roman[s[i]]< roman[s[i+1]]:
                integer = integer - roman[s[i]]
            else:
                integer = integer + roman[s[i]]
        return integer + roman[s[-1]]

Runtime: 116 ms, faster than 99.24% of Python3 online submissions for Roman to Integer.
Memory Usage: 12.7 MB, less than 100.00% of Python3 online submissions for Roman to Integer.

2.25 20. Valid Parentheses
给定关于“{}”,“[]”, "()"的字符串,判断字符串是否是有效的括号配对结果。
思路:把“{[(”存在一个list中,“}])”存在一个list中,遍历整个字符串,如果当前遍历到的字符再左括号list中,则将其存在一个栈中,若在右括号list中,则首先判断栈的长度是否为0,若不为0则栈的最后一个元素应该与当前的遍历到的字符能够配对,若配对成功则将栈的最后一个元素删除,最终遍历结束后栈中无元素即可。

class Solution:
    def isValid(self, s):
        left = ["(", "[", "{"]
        right = [")", "]", "}"]
        stack = []
        if s == [" "]:
            return True
        for obj in s:
            if obj in left:
                stack.append(obj)
            elif obj in right:
                if len(stack) == 0:
                    return False
                if left.index(stack.pop()) != right.index(obj):
                    return False
        return len(stack) == 0
        

Runtime: 40 ms, faster than 47.54% of Python3 online submissions for Valid Parentheses.
Memory Usage: 13.1 MB, less than 5.22% of Python3 online submissions for Valid Parentheses.
想了以下,其实不需要分成左右两个list,直接用一个dict存储括号之间的对应关系可能会更加高效。

class Solution:
    def isValid(self, s):
        left = {")":"(", "]":"[", "}":"{"}
        stack = []
        if s == [" "]:
            return True
        for char in s:
            if char in left.values():
                stack.append(char)
            elif char in left.keys():
                if stack == [] or left[char] != stack.pop():
                    return False
            else:
                return False
        return stack == []
        

Runtime: 40 ms, faster than 47.54% of Python3 online submissions for Valid Parentheses.
Memory Usage: 13.1 MB, less than 5.22% of Python3 online submissions for Valid Parentheses.
并没有什么提升。。。

2.26 21. Merge Two Sorted Lists
把两个list按照大小重排融合为一个list。

# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def mergeTwoLists(self, l1, l2):
        if l1 is None:
            return l2
        if l2 is None:
            return l1
        if l1 is None and l2 is None:
            return None
        head = ListNode(0)
        cur = head
        while l1 and l2:
            if l1.val > l2.val:
                cur.next = l2
                l2 = l2.next
            else:
                cur.next = l1
                l1 = l1.next            
            cur = cur.next
        cur.next = l1 or l2
        return head.next
        

Runtime: 48 ms, faster than 52.71% of Python3 online submissions for Merge Two Sorted Lists.
Memory Usage: 13.2 MB, less than 5.06% of Python3 online submissions for Merge Two Sorted Lists.

3.4 26. Remove Duplicates from Sorted Array
这个题目比较特别的一点就是不能再用一个新的序列存储,所有的modify必须都是对原有的序列进行的。思路相当于是找到两个point,一个point在遍历整个list,另一个point在储存不重复的数量。当遍历到的前后都是一样的值时,point2停下不动,出现不一样时,point2+1同时将新的值赋给list[point2+1],最终返回point2的现值+1即为不重复的list长度。

class Solution:
    def removeDuplicates(self, nums):
        if not nums:
            return 0
        tail = 0
        for i in range(1,len(nums)):
            if nums[i] != nums[tail]:
                tail +=1
                nums[tail] = nums[i]
        return tail+1

Runtime: 72 ms, faster than 58.40% of Python3 online submissions for Remove Duplicates from Sorted Array.
Memory Usage: 14.8 MB, less than 5.43% of Python3 online submissions for Remove Duplicates from Sorted Array.

在discussion中看到另一种解法,用到了OrderedDict.fromkeys(nums).keys(),直接将重复项去除了,答主解释nums[:]不会占用新的空间。https://leetcode.com/problems/remove-duplicates-from-sorted-array/discuss/11880/Python-2-liner-O(N)

def removeDuplicates(self, nums):
    nums[:] =  OrderedDict.fromkeys(nums).keys()
    return len(nums)

3.6 28. Implement strStr()

class Solution:
    def strStr(self, haystack, needle):
        if len(needle) ==0:
            return 0
        if len(needle) ==0 and len(haystack) ==0:
            return 0
        return haystack.find(needle)

Runtime: 36 ms, faster than 82.91% of Python3 online submissions for Implement strStr().
Memory Usage: 13.2 MB, less than 5.13% of Python3 online submissions for Implement strStr().

3.6 27. Remove Element

class Solution:
    def removeElement(self, nums, val):
        if not nums:
            return 0
        nums[:] = [x for x in nums if x!=val]
        return len(nums)

3.6 35. Search Insert Position
简单想法就是直接遍历整个list,比较intuitive

class Solution:
    def searchInsert(self, nums, target):
        for i in range(len(nums)):
            if nums[i]>=target:
                return i
            
        return i+1

时间复杂度O(n)
discussion中说可以用binary search

class Solution(object):
def searchInsert(self, nums, key):
    if key > nums[len(nums) - 1]:
        return len(nums)

    if key < nums[0]:
        return 0

    l, r = 0, len(nums) - 1
    while l <= r:
        m = (l + r)/2
        if nums[m] > key:
            r = m - 1
            if r >= 0:
                if nums[r] < key:
                    return r + 1
            else:
                return 0

        elif nums[m] < key:
            l = m + 1
            if l < len(nums):
                if nums[l] > key:
                    return l
            else:
                return len(nums)
        else:
            return m

还有一个据说很快的方法

def searchInsert(self, nums, target):
    return sorted(nums + [target]).index(target)

2019.07.28

22. 括号生成

给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。

例如,给出 n = 3,生成结果为:

[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        #把一组括号插入到已经生成的括号组合的某个位置即可
        #首先初始化一个res的set
        res = set(['()'])
        for i in range(n-1):   #除了初始的一个再加上n-1个括号
            tmp = set()         #用来存放每次加入一个括号之后的结果
            for j in res:        #结果集中的每一个结果都要尝试一次再各个位置加入一个括号,用set去重
                tmp.update(set([j[:k]+'()'+j[k:] for k in range(len(j))]))
            res = tmp          #赋值给结果集
        return list(res)       #列表形式输出
        

我的提交执行用时
已经战胜 75.16 % 的 python 提交记录

24.两两交换链表中的节点

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """     
        if not head:
            return head
        if not head.next:
            return head
        pre = ListNode(0)        
        cur = head
        pre.next = head
        temp = pre
        while cur != None and cur.next != None:
            next_ = cur.next
            cur.next = next_.next
            next_.next = cur
            pre.next = next_
            pre = cur
            cur = cur.next
        return temp.next

思路就是需要建立一个辅助的头节点,然后pre,cur,next三个指针进行移动
1-2-3-4变成0-1-2-3-4变成0-2-1-3-4变成0-2-1-4-3
发现while a.next!=None and a != None和while a != None and a.next != None是不一样的,应该用后者,不然会报错:NoneType object has no attribute next
执行用时 :20 ms 在所有 Python 提交中击败了88.75%的用户
内存消耗 :11.6 MB, 在所有 Python 提交中击败了43.56%的用户

31.下一个排列

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

必须原地修改,只允许使用额外常数空间。

以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

执行用时 :32 ms, 在所有 Python 提交中击败了94.66%的用户

class Solution(object):
    def nextPermutation(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        if not nums:
            return nums
        n = len(nums)-1
        while n>0 and nums[n-1]>= nums[n]:
            n-=1
        #跳出循环的就是索引值最大的a[i-1]<a[i]的i,这说明i到最后一个是降序排列,然后需要在i到结尾中找到最接近a[i-1]且大于
        #a[i-1]的数字a[k],直接从最后一个开始找就可以,交换a[i-1],a[k],然后对a[i:]排序,本来是逆序的,变成正序就可以。如果不存在跳出循环的值,那此时正好n-1就是0
        j = len(nums)-1
        if n>0:
        #需要排除倒序的情况
            while j >= n:
                if nums[j]>nums[n-1]:
                    nums[n-1],nums[j] = nums[j],nums[n-1]
                    break
                j-=1
        nums[n:] = reversed(nums[n:])
        return nums
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值