DW&LeetCode_day1(2、4、5)

DW&LeetCode_day1(2、4、5)


写在前面:

  • 从今天开始,和大家一起开始第21期的打卡学习啦,目标:坚持下来,加油!

开源内容

开源内容

学习大纲 


目录

DW&LeetCode_day1(2、4、5)

写在前面:

开源内容

学习大纲 

2.两数相加

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

5. 最长回文子串


 

20天,每天平均花费时间2小时-5小时不等,根据个人学习接受能力强弱有所浮动。

DW&LeetCode_day1(2、4、5)_第1张图片

 

 

2.两数相加

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.


示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]


示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
 

提示:

每个链表中的节点数在范围 [1, 100] 内
0 <= Node.val <= 9
题目数据保证列表表示的数字不含前导零

题目链接

    # 题解
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        dummy = ListNode()
        cur, p, q, count = dummy, l1, l2, 0
        while p or q:
            if p: p, count = p.next, count + p.val
            if q: q, count = q.next, count + q.val
            cur.next = ListNode(val=count % 10)
            cur, count = cur.next, count // 10
        if count > 0:
            cur.next = ListNode(count)
        return dummy.next

DW&LeetCode_day1(2、4、5)_第2张图片


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

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。

进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

示例 1:

输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2


示例 2:

输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5


示例 3:

输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000


示例 4:

输入:nums1 = [], nums2 = [1]
输出:1.00000


示例 5:

输入:nums1 = [2], nums2 = []
输出:2.00000
 

提示:

nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106

题目链接
 

    # 题解
    # 1.  合并数组
    # 2.  排序
    # 3.  输出中位数
    def findMedianSortedArrays(self, a: List[int], b: List[int]) -> float:
        b.extend(a)
        b=sorted(b)
        length=len(b)
        if length%2==0:
            return (b[length//2]+b[length//2-1])/2
        else:
            return b[(length-1)//2]

DW&LeetCode_day1(2、4、5)_第3张图片


5. 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。


示例 2:

输入:s = "cbbd"
输出:"bb"


示例 3:

输入:s = "a"
输出:"a"


示例 4:

输入:s = "ac"
输出:"a"
 

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母(大写和/或小写)组成


链接:题目链接

解题思路
子串问题,动态规划


1.最优子问题
dp[i][j],表示第i个字符到第j个字符是否是回文字符串
若dp[i+1][j-1]是回文字符串且s[i]==s[j],则dp[i][j]也为回文字符串


2.难点:边界问题
当s为单个字符时
初始条件:当s为三个字符时,前后相等即为回文字符串
大于三个字符时,用传递公式dp[i][j]=dp[i+1][j-1];

 

动态规划要注意递推方向

解法:中心拓展法
每个点可以作为一个中心拓展;
每两个点的中间可作为一个中心拓展;
对每个可拓展点进行拓展,返回拓展后的回文子串长度;

# 一个参考题解,这个写的很详细
 def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        len_s = len(s)
        if len_s < 2:
            return s

        # 因为是判断子串,根据子串的性质s[i:j],因此必然涉及到两层循环,也就需要定义二维数组dp
        # 状态初始化:默认为True,可以省去很多计算
        dp = [[True for _ in range(len_s)] for _ in range(len_s)]
       
        max_len = 0
        start = 0

        # 状态转移方程:表示i到j的子串是否是回文子串
        # dp[i][j] = (s[i] == s[j] and dp[i+1][j-1])
        
        # 遍历状态集:因为需要知道j-1,因此j需要从1开始
        for j in range(1, len_s):
            # 因为是子串,i一定是要小于j
            for i in range(j):
                if s[i] == s[j]:
                    # 如果收尾字符相等,那么直接取决于去掉该收尾的子串
                    dp[i][j] = dp[i+1][j-1]
                else:
                    # 如果不相等,不管子串如何,肯定不是回文
                    dp[i][j] = False

                # 更新最大长度
                if dp[i][j] and max_len < j - i:
                    max_len = j - i
                    start = i
                    
        return s[start:start+max_len+1]
#题解
    # 1. 遍历字符串的每个索引
    # 2. 判断能否向往拓展回文字符串
    def longestPalindrome(self, s: str) -> str:
        r = ''
        for i, j in [(i, j) for i in range(len(s)) for j in (0, 1)]:
            while i > -1 and i + j < len(s) and s[i] == s[i + j]: i, j = i - 1, j + 2
            r = max(r, s[i + 1:i + j], key=len)
        return '' if not s else r

DW&LeetCode_day1(2、4、5)_第4张图片


 

你可能感兴趣的:(Datawhale,LeetCode题解,leetcode,算法)