第一天刷题

题目1

  • 题号:2
  • 难度:中等
  • https://leetcode-cn.com/problems/add-two-numbers/

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

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

示例1:

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

示例2:

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

示例3:

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

思路

模拟两个数相加,结果返回一个相加之后和的链表。

同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。具体而言,如果当前两个链表处相应位置的数字为 n1,n2,进位值为carry,则它们的和n1+n2+carry;其中,答案链表处相应位置的数字为 (n1+n2+carry)%10,而新的进位值为⌊n1+n2+carry⌋。

如果两个链表的长度不同,则可以认为长度短的链表的后面有若干个 0 。

此外,如果链表遍历结束后,有carry>0,还需要在答案链表的后面附加一个节点,节点的值为 carry。

实现

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = point = ListNode(0) # 定义链表头节点
        carry = 0
        while l1 or l2: #同时遍历这两个链表的节点
            new_point = ListNode(0)
            if not l1 : # l1节点为空的情况,把该节点的值当作0
                res = l2.val+carry
                new_point.val = res%10
                carry = res // 10
                l2=l2.next
            elif not l2 : # l2节点为空的情况,把该节点的值当作0
                res = l1.val + carry
                new_point.val = res%10
                carry = res // 10
                l1=l1.next
            else : # 两个节点都有值的情况
                res = l2.val+l1.val+carry 
                # 两个节点的值相加的和与10取余为新节点
                new_point.val = res % 10 
                # 进位值是除以10取整
                carry = res // 10 
                # 同时指向下一个节点
                l2=l2.next
                l1=l1.next
            # 把计算后的节点加在point的后面
            point.next = new_point
            # 指针往后移
            point = point.next
        # 遍历完所有节点后,判断最后一次循环时是否进位,即carry是否为1
        if carry == 1 : 
            new_point = ListNode(1)
            point.next = new_point
        return head.next

分析

时间复杂度:O(max(m,n)),假设m和n分别表示l1和l2的长度,上面的算法最多重复max(m,n)次

空间复杂度:O(max(m,n)),新列表的长度最多为max(m,n) + 1

题目2

  • 题号:4
  • 难度:困难
  • https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

思路1

首先把两个有序数组合并为一个有序数组,然后根据数组长度来确定中位数,如果数组长度为偶数,那么返回两个中位数的平均值,如果数组长度为奇数,那么返回中位数。

实现1

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        m = len(nums1)
        n = len(nums2)
        nums1.extend(nums2)# 合并
        nums1.sort()# 排序		
        if (m + n) % 2 != 0:# 如果是奇数 返回中位数
            return nums1[(m + n - 1)//2]
        else:# 返回两个中位数的平均值
            return (nums1[(m + n)//2 - 1] + nums1[(m + n)//2 ]) / 2

这个时间复杂度不符合 思路比较简单

思路2

二分查找(后续补一下 现在没看懂···)


题目3

  • 题号:5
  • 难度:中等
  • https://leetcode-cn.com/problems/longest-palindromic-substring/

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2

输入: "cbbd"
输出: "bb"

示例 3

输入: "a"
输出: "a"

思路1

暴力法,列举所有的子串,判断该子串是否为回文

使用两个for循环遍历所有子串

实现1

执行结果:超出时间限制

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        if len(s) < 2:
            return s
        begin = 0
        maxlen= 1
        for i in range(len(s)-1):
            for j in range(i+1,len(s)):
                if ((j - i + 1) > maxlen) & (self.if_huiwen(s,i,j)):
                    maxlen = j - i + 1
                    begin = i
        return s[begin:begin+maxlen]
    def if_huiwen(self,s,left,right):
        while left<right:
            if s[left] != s[right]:
                return False
            left +=1
            right -= 1
        return True

分析1

时间复杂度:O(n^3)

空间复杂度:O(1)

思路2

动态规划:后续补上 之前没学过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值