leetcode笔记

2. 两数相加

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        result = cur = ListNode(0)
        carry = 0
        while l1 or l2:
            x = l1.val if l1 else 0
            y = l2.val if l2 else 0
            carry, mod = divmod(carry + x + y, 10)
            cur.next = ListNode(mod)
            cur = cur.next
            if l1: l1 = l1.next
            if l2: l2 = l2.next
        if carry: cur.next = ListNode(1)
        return result.next

3. 无重复字符的最长子串

暴力法:O(n^3)
滑动窗口: O(n), 通过使用 HashSet 作为滑动窗口,我们可以用O(1)的时间来完成对字符是否在当前的子字符串中的检查。滑动窗口是数组/字符串问题中常用的抽象概念。 窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合,即 [i,j)(左闭,右开)。而滑动窗口是可以将两个边界向某一方向“滑动”的窗口。例如,我们将 [i,j)向右滑动 11 个元素,则它将变为 [i+1,j+1)(左闭,右开)。
回到我们的问题,我们使用 HashSet 将字符存储在当前窗口 [i,j)最初 (j=i)中。 然后我们向右侧滑动索引 j,如果它不在 HashSet 中,我们会继续滑动 j。直到 s[j] 已经存在于 HashSet 中。此时,我们找到的没有重复字符的最长子字符串将会以索引 i 开头。如果我们对所有的 i 这样做,就可以得到答案。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        st = {}
        i, ans = 0, 0 # i 是开始位置
        for j in range(len(s)):
            if s[j] in st:
                i = max(st[s[j]], i) # 原来开始的位置和s[j]重复的位置,取大的那个
            ans = max(ans, j - i + 1)
            st[s[j]] = j + 1 # 更新当前字符在 hashset 中存储的位置,hashset 存储了一个窗口中字符的位置
        return ans;

5. 最长回文子串

可以用动态规划
但更优的是中心扩展算法,回文可以从它的中心展开,并且只有 2n−1 个这样的中心。

class Solution:
    def longestPalindrome(self, s: str) -> str:
        if not s: return ""
        start = end = 0
        for i in range(len(s)):
            len1 = self.expand_around_center(s, i, i)
            len2 = self.expand_around_center(s, i, i + 1)
            m_len = max(len1, len2)
            if m_len > end - start:
                start = i - (m_len - 1) // 2
                end = i + m_len // 2
        return s[start:end + 1]
    
    def expand_around_center(self, s, left, right):
        L, R = left, right
        while L >= 0 and R < len(s) and s[L] == s[R]:
            L -= 1
            R += 1
        return R - L -1

你可能感兴趣的:(学习)