一枚菜鸟的leetcode刷题笔记 - Day 1

一枚菜鸟的leetcode刷题笔记 - Day 1

2 - 两数相加

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        num1, num2 = 0, 0
        order = 1
        while l1:
            num1 += l1.val * order
            l1 = l1.next
            order *= 10
        order = 1
        while l2:
            num2 += l2.val * order
            l2 = l2.next
            order *= 10
        num = num1 + num2

        addList = ListNode()
        head = addList
        if num == 0:
            addList.next = ListNode(val = int(0))
        else:
            while num != 0:
                addList.next = ListNode(val = int(num % 10))
                num = num // 10
                addList = addList.next
        return head.next

这个解法主要是先把两数和求出来,再通过取余和取整操作拆分得到的数。这样避免了在链表层面直接操作带来的进位问题。

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        newList = ListNode()    #新建一个链表存储和
        head= newList   #存储头节点位置
        carry = 0    #carry代表是否需要进位
        while l1 and l2:
            addVal = l1.val + l2.val + carry
            head.next = ListNode(val= addVal % 10)
            carry = 1 if addVal >= 10 else 0
            l1, l2, head = l1.next, l2.next, head.next
        while l1:
            addVal = l1.val + carry
            head.next = ListNode(val= addVal % 10)
            carry = 1 if addVal >= 10 else 0
            l1, head = l1.next, head.next
        while l2:
            addVal = l2.val + carry
            head.next = ListNode(val= addVal % 10)
            carry = 1 if addVal >= 10 else 0
            l2, head = l2.next, head.next
        if carry == 1:
            #要考虑当两个链表都走完还有进位的情况,最终链表的位数也许比输入两链表中的长者还多一位
            #例如[9,9,9,9,9,9,9]&[9,9,9,9]
            head.next = ListNode(val = 1)
        return newList.next

这个解法直接在链表层面的操作,要注意进位的处理,尤其要留心当两个链表都走完还有进位的情况,如[9,9,9,9,9,9,9]&[9,9,9,9]

4 - 寻找两个正序数组的中位数

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        nums1.extend(nums2)
        nums1.sort()
        n = len(nums1)
        if n % 2 == 1:   #判断为奇数
            return nums1[int((n-1)/2)]
        else:
            return (nums1[int((n-1)/2)] + nums1[int((n+1)/2)]) / 2

这个解法实际上在偷懒,直接用了python列表自带的sort函数【满足O(log(m+n))】,避开了排序过程。

关于Python List sort()方法:
list.sort(cmp=None, key=None, reverse=False)

  • cmp – 可选参数, 如果指定了该参数会使用该参数的方法进行排序。
  • key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse – 排序规则,reverse = True 降序, reverse = False 升序(默认)。
    该方法没有返回值,但是会对列表的对象进行排序。

python中的sorted/list.sort()排序,用的Timsort算法
一个补充博客

5 - 最长回文子串

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if len(s) <= 1:
            return s
        #动态规划就是维护一个表格,这里用一个二维数组表示
        table = [[False for _ in range(len(s))] for _ in range(len(s))]
        #表格对角线上肯定是True,因为这些元素对应着单个字符的情况
        for i in range(len(s)):
            table[i][i] = True

        maxLength = 1   #记录最长子串的长度
        start = 0   #记录最长子串的起始位置
        for j in range(1, len(s)):
            for k in range(0, j):
                if s[k] == s[j]:
                    if j-k+1 <= 3:
                        table[k][j] = True
                    else:
                        table[k][j] = table[k+1][j-1]
                        #遍历顺序很重要,table[k+1][j-1]一定要在table[k][j]之前被遍历过
                
                if table[k][j]:
                    if j-k+1 > maxLength:
                        maxLength = j-k+1
                        start = k
        return s[start:start+maxLength]

这是我做的第一道关于动态规划的题目,参考了动态规划、中心扩散、Manacher 算法,上面的博文讲的很清晰。

动态规划就是在填一个表格,目前我理解的动态规划的几个要素:

  1. 状态,即表格的每个位置,这里每个状态就是table[k][j],它表示s[k,j+1]是否是回文串
  2. 状态转移,即本解法中的table[k][j] = table[k+1][j-1],表示s[k,j+1]是否是回文串与s[k+1,j]是否是回文串之间的关系。这可以说是最重要的一步。其实很简单,如果s[k]=s[j],且s[k+1,j]是回文串,那么s[k,j+1]一定是回文串。
  3. 出口,即最底层的情况在哪里。这题中,当只有两个字符如’ss’或者三个字符如’sos’,即j-k+1=2或者3的时候,可以直接定义状态的值(True or False)

动态规划乍一看很像递归,都是要找到最基础的情况,都是要找情况之间的联系。但是它与递归最重要的区别是,递归到某一层的时候,这一层的问题实际并未解决,只是暂存并打开了比之更简单的一层,一直递归到最基本的问题,才逐渐开始解题。但动态规划不同,到某一个状态,它的前一个状态是已经解决的,直接根据状态转移即可求得此时状态的值,因此每一个状态在当下即可求得其取值。也因此,动态规划填充表格的顺序特别重要,即table[k+1][j-1]一定在table[k][j]之前被填充。

你可能感兴趣的:(leetcode,leetcode,python,链表,算法)