646. 最长数对链(动态规划)

117 阅读2分钟

image.jpeg

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目解析

    • 给出数对的个数在 [1, 1000] 范围内。

二、思路分析:

我们拿到本题,题目内容要求对数组中数对进行连接🔗,数对中第一个数字小于第二个数字,那么连接最长数对链是按照什么规则连接的,继续审题如下:

  • 数对[a,b]中的两个元素只存在 a < b
  • 当数对1[a,b]和数对2[c,d],当b<c时两个数对才能被连接
  • 在存在n个数对的数组中,结果需要找到最长数对链的长度

根据以上内容,解答本题我们可以使用贪心方法来模拟,思路如下:

  • 方法一:贪心算法

    • 数对中元素存在 pairs[i][0] 一定小于 pairs[i][1]
    • 首先对pairs数组进行按照升序排序,pairs.sort()(这里有坑)
    • 定义临时变量tmp,初始化pairs[0][1],并将结果变量ans初始化为1
    • 使用for循环遍历pairs数组1~len(pairs)范围,当pairs[index][0]大于 tmp时,则ans结果进行+1,tmp被重新赋值为pairs[index][1]
    • 按照上述思路我们提交代码,发现case跑不过 image.png
    • 查看原因,发现pairs.sort()默认是按照数对中第一个数字排序的,但是本题中我们需要比较多是第二个数字的情况,因此可以直接使用lambda匿名函数 key = lambda x:x[1]
    • 根据以上思路和优化,我们使用python快速实现,代码如下:
      class Solution(object):
          def findLongestChain(self, pairs):
              """
              :type pairs: List[List[int]]
              :rtype: int
              """
              pairs.sort(key=lambda x: x[1])
              ans = 1
              tmp = pairs[0][1]
              for index in range(1,len(pairs)):
                  if tmp < pairs[index][0]:
                      ans +=1
                      tmp = pairs[index][1]
              return ans
      
      
  • 方法二:动态规划

    • 在该题中,我们需要找到pairs[index][0] > pairs[j][1]的索引j,则ans[index]取其中ans[index]与ans[j]+1的最大值
    • 所以使用动态规划的方式可以快速实现,定义一个临时数组ans长度为len(pairs)并且其所有元素初始值为1
    • 使用两个for循环,第一层for循环遍历pairs.sort()数组每一对数对pairs[index]
    • 再第二层for循环中,遍历index前的所有数对,找到pairs[index][0]>pairs[j][1]的数对
    • 并将pairs[index]在pairs[j]+1,pairs[index]中选择最大的更新
    • 最后遍历完pairs数组,返回ans最末尾是数值
    class Solution(object):
        def findLongestChain(self, pairs):
            """
            :type pairs: List[List[int]]
            :rtype: int
            """
            pairs.sort()
            ans = [1]*len(pairs)
            for index in range(len(pairs)):
                for j in range(index):
                    if pairs[index][0] > pairs[j][1]:
                        ans[index] = max(ans[index],ans[j]+1)
    
            return ans[-1]
    

三、总结:

本题考察对区间拼接场景的处理,在该题中最有优解为一次遍历的贪心算法,但是前提需要将pairs数组中按照第二个数字进行排序,AC提交记录如下:

image.png

  • 时间复杂度:O(nlogn),n为pairs数组长度
  • 空间复杂度:O(logn),pairs数组排序空间

以上是本期内容,欢迎大佬们点赞评论,下期见~~~