From f645dd591881a31985d7930504ec6ad8a07d5fc6 Mon Sep 17 00:00:00 2001 From: AC_Oier Date: Sat, 3 Sep 2022 15:21:56 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8feat:=20Add=20646?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "Index/\344\272\214\345\210\206.md" | 1 + "Index/\345\272\217\345\210\227 DP.md" | 1 + "Index/\346\216\222\345\272\217.md" | 1 + ...52\345\277\203\347\256\227\346\263\225.md" | 1 + ...10\344\270\255\347\255\211\357\274\211.md" | 112 ++++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 "LeetCode/641-650/646. \346\234\200\351\225\277\346\225\260\345\257\271\351\223\276\357\274\210\344\270\255\347\255\211\357\274\211.md" diff --git "a/Index/\344\272\214\345\210\206.md" "b/Index/\344\272\214\345\210\206.md" index e7621df4..1486d0eb 100644 --- "a/Index/\344\272\214\345\210\206.md" +++ "b/Index/\344\272\214\345\210\206.md" @@ -32,6 +32,7 @@ | [532. 数组中的 k-diff 数对](https://leetcode.cn/problems/k-diff-pairs-in-an-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/k-diff-pairs-in-an-array/solution/by-ac_oier-ap3v/) | 中等 | 🤩🤩🤩🤩 | | [540. 有序数组中的单一元素](https://leetcode-cn.com/problems/single-element-in-a-sorted-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/single-element-in-a-sorted-array/solution/gong-shui-san-xie-er-duan-xing-fen-xi-yu-17nv/) | 中等 | 🤩🤩🤩🤩 | | [611. 有效三角形的个数](https://leetcode-cn.com/problems/valid-triangle-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-triangle-number/solution/gong-shui-san-xie-yi-ti-san-jie-jian-dan-y1we/) | 中等 | 🤩🤩🤩🤩 | +| [646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-length-of-pair-chain/solution/by-ac_oier-z91l/) | 中等 | 🤩🤩🤩🤩🤩 | | [658. 找到 K 个最接近的元素](https://leetcode.cn/problems/find-k-closest-elements/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-k-closest-elements/solution/by-ac_oier-8xh5/) | 中等 | 🤩🤩🤩🤩 | | [668. 乘法表中第k小的数](https://leetcode.cn/problems/kth-smallest-number-in-multiplication-table/) | [LeetCode 题解链接](https://leetcode.cn/problems/kth-smallest-number-in-multiplication-table/solution/by-ac_oier-7pmt/) | 困难 | 🤩🤩🤩🤩🤩 | | [704. 二分查找](https://leetcode-cn.com/problems/binary-search/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/binary-search/solution/gong-shui-san-xie-yun-yong-er-fen-zhao-f-5jyj/) | 简单 | 🤩🤩🤩🤩🤩 | diff --git "a/Index/\345\272\217\345\210\227 DP.md" "b/Index/\345\272\217\345\210\227 DP.md" index 358778e6..7b0195ca 100644 --- "a/Index/\345\272\217\345\210\227 DP.md" +++ "b/Index/\345\272\217\345\210\227 DP.md" @@ -9,6 +9,7 @@ | [522. 最长特殊序列 II](https://leetcode.cn/problems/longest-uncommon-subsequence-ii/) | [LeetCode 题解链接](https://leetcode.cn/problems/longest-uncommon-subsequence-ii/solution/by-ac_oier-vuez/) | 中等 | 🤩🤩🤩🤩🤩 | | [583. 两个字符串的删除操作](https://leetcode-cn.com/problems/delete-operation-for-two-strings/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/delete-operation-for-two-strings/solution/gong-shui-san-xie-cong-liang-chong-xu-li-wqv7/) | 中等 | 🤩🤩🤩🤩 | | [629. K个逆序对数组](https://leetcode-cn.com/problems/k-inverse-pairs-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/k-inverse-pairs-array/solution/gong-shui-san-xie-yi-dao-xu-lie-dp-zhuan-tm01/) | 中等 | 🤩🤩🤩🤩🤩 | +| [646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-length-of-pair-chain/solution/by-ac_oier-z91l/) | 中等 | 🤩🤩🤩🤩🤩 | | [673. 最长递增子序列的个数](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-longest-increasing-subsequence/solution/gong-shui-san-xie-lis-de-fang-an-shu-wen-obuz/) | 中等 | 🤩🤩🤩🤩 | | [689. 三个无重叠子数组的最大和](https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/maximum-sum-of-3-non-overlapping-subarrays/solution/gong-shui-san-xie-jie-he-qian-zhui-he-de-ancx/) | 困难 | 🤩🤩🤩🤩 | | [740. 删除并获得点数](https://leetcode-cn.com/problems/delete-and-earn/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/delete-and-earn/solution/gong-shui-san-xie-zhuan-huan-wei-xu-lie-6c9t0/) | 中等 | 🤩🤩🤩🤩🤩 | diff --git "a/Index/\346\216\222\345\272\217.md" "b/Index/\346\216\222\345\272\217.md" index cebe926b..581c7760 100644 --- "a/Index/\346\216\222\345\272\217.md" +++ "b/Index/\346\216\222\345\272\217.md" @@ -14,6 +14,7 @@ | [581. 最短无序连续子数组](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray/solution/gong-shui-san-xie-yi-ti-shuang-jie-shuan-e1le/) | 中等 | 🤩🤩🤩🤩 | | [611. 有效三角形的个数](https://leetcode-cn.com/problems/valid-triangle-number/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/valid-triangle-number/solution/gong-shui-san-xie-yi-ti-san-jie-jian-dan-y1we/) | 中等 | 🤩🤩🤩🤩 | | [645. 错误的集合](https://leetcode-cn.com/problems/set-mismatch/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/set-mismatch/solution/gong-shui-san-xie-yi-ti-san-jie-ji-shu-s-vnr9/) | 简单 | 🤩🤩🤩 | +| [646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-length-of-pair-chain/solution/by-ac_oier-z91l/) | 中等 | 🤩🤩🤩🤩🤩 | | [703. 数据流中的第 K 大元素](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/solution/jian-da-ti-de-duo-chong-jie-fa-mou-pao-p-d1qi/) | 简单 | 🤩🤩🤩 | | [825. 适龄的朋友](https://leetcode-cn.com/problems/friends-of-appropriate-ages/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/friends-of-appropriate-ages/solution/gong-shui-san-xie-yi-ti-shuang-jie-pai-x-maa8/) | 中等 | 🤩🤩🤩🤩 | | [937. 重新排列日志文件](https://leetcode-cn.com/problems/reorder-data-in-log-files/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/reorder-data-in-log-files/solution/by-ac_oier-ap28/) | 简单 | 🤩🤩🤩🤩🤩 | diff --git "a/Index/\350\264\252\345\277\203\347\256\227\346\263\225.md" "b/Index/\350\264\252\345\277\203\347\256\227\346\263\225.md" index 4d68404a..d9aafef3 100644 --- "a/Index/\350\264\252\345\277\203\347\256\227\346\263\225.md" +++ "b/Index/\350\264\252\345\277\203\347\256\227\346\263\225.md" @@ -14,6 +14,7 @@ | [564. 寻找最近的回文数](https://leetcode-cn.com/problems/find-the-closest-palindrome/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/find-the-closest-palindrome/solution/gong-shui-san-xie-tan-xin-fen-xi-shang-x-vtr6/) | 困难 | 🤩🤩🤩 | | [575. 分糖果](https://leetcode-cn.com/problems/distribute-candies/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/distribute-candies/solution/gong-shui-san-xie-noxiang-xin-ke-xue-xi-pjjxo/) | 简单 | 🤩🤩🤩🤩 | | [630. 课程表 III](https://leetcode-cn.com/problems/course-schedule-iii/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/course-schedule-iii/solution/gong-shui-san-xie-jing-dian-tan-xin-yun-ghii2/) | 困难 | 🤩🤩🤩🤩 | +| [646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-length-of-pair-chain/solution/by-ac_oier-z91l/) | 中等 | 🤩🤩🤩🤩🤩 | | [757. 设置交集大小至少为2](https://leetcode.cn/problems/set-intersection-size-at-least-two/) | [LeetCode 题解链接](https://leetcode.cn/problems/set-intersection-size-at-least-two/solution/by-ac_oier-3xn6/) | 困难 | 🤩🤩🤩🤩 | | [765. 情侣牵手](https://leetcode-cn.com/problems/couples-holding-hands/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/couples-holding-hands/solution/liang-chong-100-de-jie-fa-bing-cha-ji-ta-26a6/) | 困难 | 🤩🤩🤩 | | [768. 最多能完成排序的块 II](https://leetcode.cn/problems/max-chunks-to-make-sorted-ii/) | [LeetCode 题解链接](https://leetcode.cn/problems/max-chunks-to-make-sorted-ii/solution/by-ac_oier-z4wt/) | 困难 | 🤩🤩🤩🤩🤩 | diff --git "a/LeetCode/641-650/646. \346\234\200\351\225\277\346\225\260\345\257\271\351\223\276\357\274\210\344\270\255\347\255\211\357\274\211.md" "b/LeetCode/641-650/646. \346\234\200\351\225\277\346\225\260\345\257\271\351\223\276\357\274\210\344\270\255\347\255\211\357\274\211.md" new file mode 100644 index 00000000..582bc164 --- /dev/null +++ "b/LeetCode/641-650/646. \346\234\200\351\225\277\346\225\260\345\257\271\351\223\276\357\274\210\344\270\255\347\255\211\357\274\211.md" @@ -0,0 +1,112 @@ +### 题目描述 + +这是 LeetCode 上的 **[646. 最长数对链](https://leetcode.cn/problems/maximum-length-of-pair-chain/solution/by-ac_oier-z91l/)** ,难度为 **中等**。 + +Tag : 「贪心」、「排序」、「二分」、「序列 DP」、「LIS」 + + + +给出 `n` 个数对。 在每一个数对中,第一个数字总是比第二个数字小。 + +现在,我们定义一种跟随关系,当且仅当 `b < c` 时,数对 $(c, d)$ 才可以跟在 $(a, b)$ 后面。我们用这种形式来构造一个数对链。 + +给定一个数对集合,找出能够形成的最长数对链的长度。你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。 + +示例: +``` +输入:[[1,2], [2,3], [3,4]] + +输出:2 + +解释:最长的数对链是 [1,2] -> [3,4] +``` + +提示: +* 给出数对的个数在 $[1, 1000]$ 范围内。 + +--- + +### 排序 + 贪心 DP + +起始先将 `pairs` 根据第一维排升序(或直接双关键字排升序)。 + +考虑定义 $f[i]$ 为以 $pairs[i]$ 为结尾的最长数对链长度,所有 $f[i]$ 中的最大值为答案。 + +不失一般性考虑 $f[i]$ 该如何转移:不难发现 $f[i]$ 为所有满足「下标范围在 $[0, i - 1]$,且 $pairs[j][1] < pairs[i][0]$」条件的 $f[j] + 1$ 的最大值。 + +但实际上,我们只需要从 $j = i - 1$ 开始往回找,找到第一个满足 $pairs[j][1] < pairs[i][0]$ 的位置 $j$ 即可。 + +容易证明该做法的正确性:**假设贪心解(该做法)找到的位置 $j$ 不是最优位置,即存在比 $j$ 更小的合法下标 $j'$ 满足 $f[j'] > f[j]$。根据我们的排序规则必然有 $pairs[j'][0] <= pairs[j][0]$ 的性质,则可知 $pairs[j]$ 必然可以代替 $pairs[j']$ 接在原本以 $pairs[j']$ 为结尾的最优数链上(最优数链长度不变,结果不会变差),则至少有 $f[j'] = f[j]$。** + +代码: +```Java +class Solution { + public int findLongestChain(int[][] pairs) { + Arrays.sort(pairs, (a,b)->a[0]-b[0]); + int n = pairs.length, ans = 1; + int[] f = new int[n]; + for (int i = 0; i < n; i++) { + f[i] = 1; + for (int j = i - 1; j >= 0 && f[i] == 1; j--) { + if (pairs[j][1] < pairs[i][0]) f[i] = f[j] + 1; + } + ans = Math.max(ans, f[i]); + } + return ans; + } +} +``` +* 时间复杂度:排序的复杂度为 $O(n\log{n})$;不考虑剪枝效果 `DP` 复杂度为 $O(n^2)$。整体复杂度为 $O(n^2)$ +* 空间复杂度:$O(n)$ + +--- + +### 排序 + 贪心 DP(优化转移) + +根据上述分析,我们知道对于一个特定的 $pairs[i]$ 而言,其所有合法(满足条件 $pairs[j][1] < pairs[i][0]$)的前驱状态 $f[j]$ 必然是非单调递增的。 + +根据 `LIS` 问题的贪心解的思路,我们可以额外使用一个数组记录下特定长度数链的最小结尾值,从而实现二分找前驱状态。 + +具体的,创建 $g$ 数组,其中 $g[len] = x$ 代表数链长度为 $len$ 时结尾元素的第二维最小值为 $x$。 + +如此一来,当我们要找 $f[i]$ 的前驱状态时,等价于在 $g$ 数组中找满足「小于 $pairs[i][0]$」的最大下标。同时,我们不再需要显式维护 $f$ 数组,只需要边转移变更新答案即可。 + +> **不了解 `LIS` 问题的同学可以看前置 🧀 : [LCS 问题与 LIS 问题的相互关系,以及 LIS 问题的最优解证明](https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247487814&idx=1&sn=e33023c2d474ff75af83eda1c4d01892) 🎉🎉🎉** + +代码: +```Java +class Solution { + public int findLongestChain(int[][] pairs) { + Arrays.sort(pairs, (a,b)->a[0]-b[0]); + int n = pairs.length, ans = 1; + int[] g = new int[n + 10]; + Arrays.fill(g, 0x3f3f3f3f); + for (int i = 0; i < n; i++) { + int l = 1, r = i + 1; + while (l < r) { + int mid = l + r >> 1; + if (g[mid] >= pairs[i][0]) r = mid; + else l = mid + 1; + } + g[r] = Math.min(g[r], pairs[i][1]); + ans = Math.max(ans, r); + } + return ans; + } +} +``` +* 时间复杂度:排序的复杂度为 $O(n\log{n})$;`DP` 复杂度为 $O(n\log{n})$。整体复杂度为 $O(n\log{n})$ +* 空间复杂度:$O(n)$ + +--- + +### 最后 + +这是我们「刷穿 LeetCode」系列文章的第 `No.646` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。 + +在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。 + +为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。 + +在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。 +