TLP-Task01学习笔记


本篇为Datawhale组队学习计划第21期LeetCode精选题目组Task01学习笔记。
初学,时间有点仓促,很多解法没有详细分析,未来会修改,见谅。
所有题目均参考了Datawhale学习文档,开源地址:
https://github.com/datawhalechina/team-learning-program/tree/master/LeetCodeTencent

002 两数相加

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers

给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

提示

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

示例:

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

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

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

思路

两数相加,主要考虑链表长度对齐(遍历)和进位的问题。
基本思路:遍历,将相同位置的节点值相加;满十进位,加到新的一位去。

Python实现

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        dummy = ListNode()
        cur, count = dummy, 0
        while l1 or l2:
            if l1: # l1不为空
                count += l1.val #节点值加和
                l1 = l1.next #更新
            if l2: 
                count, l2 = count + l2.val, l2.next
            cur.next = ListNode(count % 10) #取余数操作,更新链表
            cur,count = cur.next, count // 10
        if count != 0:
            cur.next = ListNode(count)
        return dummy.next

执行用时68ms。后续优化主要在遍历方法方向。

参考:
https://cloud.tencent.com/developer/article/1478036
https://leetcode-cn.com/problems/add-two-numbers/solution/liang-ge-shu-xiang-jia-zui-rong-yi-li-jie-de-jie-f/

004 寻找两个正序数组的中位数

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays

给定两个大小为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的中位数。
进阶:你能设计一个时间复杂度为 O(log (m+n)) 的算法解决此问题吗?

扫描二维码关注公众号,回复: 12277627 查看本文章

示例

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

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

提示

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

思路

个人推荐LeetCode题解,可以把常见的思路都了解一下。
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/
https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/4-xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-shu/
题目要求时间复杂度O(log (m+n)),又是有序数组,想到采用二分法解题(二分法总是搭配有序数组,遇到时都可以考虑能不能使用)。
数组长度2k或2k-1,求第k小的数字,第一篇题解中操作方法说得很详细。
不断对比两数列的第k/2个数,若A数列的第k/2个数小于B数列的,说明A数列前面几项都小于所需数,全部排除。不断更新k,依此类推。
注意考虑数组长度不到k/2的问题:

每次比较 min(k/2,len(数组) 对应的数字,把小的那个对应的数组的数字排除,将两个新数组进入递归,并且 k
要减去排除的数字的个数。递归出口就是当 k=1 或者其中一个数字长度是 0 了。

代码实现(咕)

https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-2/585372
这篇代码注释比较详细,结合本篇题解看就足够了。感觉自己再解释也不如直接看原文来得好。个人想等二分法这里攒几道题可以做一个专题。

其他技巧

添加#来避免奇偶个数问题,采用切割的策略可进一步降低复杂度。

005 最长回文子串

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring

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

示例

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

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

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

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

提示:

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

思路

学习文档中主要介绍了暴力法和动态规划两种。暴力法时间复杂度O(n^3),就一直超时。动态规划与回文通常是搭配的。(但来不及写了就只能先放一个暴力在这里)
代码来源及参考:
https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/

Python实现(暴力解法超时)

class Solution:
    def longestPalindrome(self, s: str) -> str:
        size = len(s)
        if size < 2: return s #一个字符时直接输出
        max_len, res = 1, s[0]

        # 枚举所有长度大于等于 2 的子串
        #左、右边界,验证回文串,都与整个数组有关,导致时间复杂度O(n^3)
        for i in range(size - 1):
            for j in range(i + 1, size):
                if j - i + 1 > max_len and self.__valid(s, i, j):
                    max_len,res = j - i + 1,s[i:j + 1]
        return res

    def __valid(self, s, left, right):
        # 验证子串 s[left, right] 是否为回文串
        while left < right:
            if s[left] != s[right]:
                return False
            left += 1
            right -= 1
        return True
        

猜你喜欢

转载自blog.csdn.net/cosima0/article/details/112498367