LeetCode 368. Largest Divisible Subset

简介: 给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (Si,Sj) 都要满足:Si % Sj = 0 或 Sj % Si = 0。如果有多个目标子集,返回其中任何一个均可。

v2-b620f458cb127c279976113ff9c04e2e_r.jpg

Description



Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies:

Si % Sj = 0 or Sj % Si = 0.


If there are multiple solutions, return any subset is fine.


Example 1:


Input: [1,2,3]
Output: [1,2] (of course, [1,3] will also be ok)


Example 2:


Input: [1,2,4,8]
Output: [1,2,4,8]


描述



给出一个由无重复的正整数组成的集合,找出其中最大的整除子集,子集中任意一对 (Si,Sj) 都要满足:Si % Sj = 0 或 Sj % Si = 0。


如果有多个目标子集,返回其中任何一个均可。


示例 1:


输入: [1,2,3]
输出: [1,2] (当然, [1,3] 也正确)


示例 2:


输入: [1,2,4,8]
输出: [1,2,4,8]


思路


  • 这道题目的做法借鉴了第 300 题 Longest Increasing Subsequence 的思路。
  • 对数组从小到大排序;
  • 我们首先求得在给定的数组中,满足条件的数构成的新数组的长度;然后再去求得对应的数组是什么;
  • 声明一个 count 数组,count[i] 表示给定数组 num 中,以数字 num[i] 作为结尾能够形成的满足条件的最大数组长度;
  • 声明一个 path 数组,用于记录数字 num[i] 的上一个有效数字的索引;
  • 因为在求 count[i] 时,我们会遍历 num[i-1] 到 num[0], 如果 num[i] % num[j] ==0 (j 的范围是 [i-1,0]); 那么 count[i] = max(count[i],count[j]+1);并且如果 count[j]+1 更大,说明 nums[i] 可以追加到 num[j] 后面,于是更新 path[i]=j;


# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-06-14 11:17:30
# @Last Modified by:   何睿
# @Last Modified time: 2019-06-14 13:09:36
from typing import List
class Solution:
    def largestDivisibleSubset(self, nums: List[int]) -> List[int]:
        if not nums: return []
        # max_count 用于记录满足条件的数构成的数组的最大长度
        # end 用于记录满足条件的数的最后一个数的索引
        max_count, end = 1, 0
        count, path = [1] * len(nums), [0] * len(nums)
        nums.sort()
        for i in range(1, len(nums)):
            for j in range(i - 1, -1, -1):
                # 确定数字num[i] 可以追加到前面的哪一个数字中
                if nums[i] % nums[j] == 0 and count[j] + 1 > count[i]:
                    count[i] = count[j] + 1
                    path[i] = j
            # 如果当前的数比 max_count,说明 nums[i] 是的需要的结果数组扩大了
            # 记下 i 的位置
            if count[i] >= max_count:
                max_count = count[i]
                end = i
        res = []
        for _ in range(max_count):
            res.append(nums[end])
            end = path[end]
        return res

源代码文件在 这里


目录
相关文章
Leetcode 368. Largest Divisible Subset思路及详解
这里有个很简单的数学性质,就是整除的传递性,如果a%b==0 且 b%c == 0,那么a%c == 0,说白了如果c是b的因子,b又是a的因子,那么c肯定是a的因子。这样我们就可以在数组中找出很多整除链(a->b->c->d,其中b是a的因子,c是b的因子,d是c的因子),这样的链条就满足两两整除的条件,题目就变成了求最长的链条。 先上代码,然后我再解释下我的代码。
55 0
|
4月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
65 6
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
58 4
|
5月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
130 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
57 1
|
4月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
5月前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
78 7
|
5月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
60 5