Leetcode之 largest divisible set

来源:互联网 发布:淘宝客服要开通管理 编辑:程序博客网 时间:2024/06/01 08:54

题目

题目地址 :https://leetcode.com/problems/largest-divisible-subset/

题意解析

给定一个数组,这个数组数唯一且为正数,求在这个数组中,满足能整除的最大集合。

求解

很自然地想到用动态规划,因为满足重叠子问题和最优子结构
重叠子问题:整个数组的最大集合,可以认为是多个子问题组成的
最优子结构:反证法,显而易见。


定义最优解:最大集合是什么。

定义最优解的值:最大集合有多少个数。

定义 f[i]表示从0到i最大能整除集合里的个数。

递归式求解最优解的值:

f[i]= max{f[i],f[j]+1}    if nums[i]%nums[j]==0

其中 j从i-1 downto 0

初始化条件:对于每个f[i],至少有i%i ==0;定义为1;

根据题意需要记录集合的内容,故需要记录每一步执行的index


Code

ac代码

import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.List;/** * Created by loveqh on 2016/8/13. */public class LargestDivisibleSet {    public List<Integer> largestDivisibleSubset(int[] nums) {        List<Integer> result = new ArrayList<Integer>();        Arrays.sort(nums);        int[] f = new int[nums.length];        int[] pre = new int[nums.length];        int max = -1;        int index = -1;        //初始化f 和前导        for (int i = 0; i < f.length; i++) {            f[i] = 1;            pre[i] = -1;        }        if (nums.length == 1) {            result.add(nums[0]);            return result;        }        for (int i = 1; i < nums.length; i++) {            //一轮循环,找到从0到i的可整除集合的长度            for (int j = i - 1; j >= 0; j--) {                if (nums[i] % nums[j] == 0 && (f[i] < f[j] + 1)) {                    f[i] = f[j] + 1;                    //记录i的前导                    pre[i] = j;                }            }            //relax max的值            if (max < f[i]) {                max = f[i];                index = i;            }        }        if (index != -1) {            result.add(nums[index]);        }        while (index > 0) {            if (pre[index]!=-1){                result.add(nums[pre[index]]);                index = pre[index];            }else {                break;            }        }        //求得的result为逆序的,应该转化为开始的样子        Collections.reverse(result);        return result;    }    public static void main(String[] args) {        int[] a = {546,669};        List<Integer> res = new LargestDivisibleSet().largestDivisibleSubset(a);        for (Integer value : res) {            System.out.print(value + "   ");        }    }}
0 0
原创粉丝点击