368. 最大整除子集(类似LIS)

368. 最大整除子集

先对数组排序,然后就很像最长上升子序列了,dp[i]就表示以nums[i]结尾的最大整除子集。

转移方程:dp[i] = max{ dp[j] + 1} (0 <= j < i 且 A[j]%A[i] == 0)

初始化:dp[i] = 1 (0 <= i < nums.length),另设路径数组path,用来记录回溯的路线。

目标:max{dp[i]} ( 0 <= i < = N)

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

空间复杂度:O(n)

class Solution {
	public List<Integer> largestDivisibleSubset(int[] nums) {
		int n = nums.length;
		int[] dp = new int[n];
		int[] path = new int[n];
        //初始化
		Arrays.fill(dp, 1);
		Arrays.fill(path, -1);
		Arrays.sort(nums);	//排序时间复杂度O(nlogn)
        
        //dp
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < i; j++) {
				if (nums[i] % nums[j] == 0 && dp[i] < dp[j] + 1) {
					dp[i] = dp[j] + 1;
					path[i] = j; // 下标为i的元素是从j来的
				}
			}
		}
        
        //找出dp最大的下标,作为回溯起始位置
		int maxindex = -1;
		int max = 0;
		for (int i = 0; i < n; i++) {
			if (dp[i] > max) {
				max = dp[i];
				maxindex = i;
			}
		}
		List<Integer> res = new ArrayList<>();
		if(maxindex == -1)
			return res;
        
        //回溯路线
		res.add(nums[maxindex]);
		while(path[maxindex] != -1) {
			res.add(0,nums[path[maxindex]]);
			maxindex = path[maxindex];
		}
		return res;
	}
}

这个题是否可以像LIS那样优化为O(nlogn)呢?我认为不可以,因为遍历到的nums[i],并不是只依赖dp,还要看nums[i]是否能整除前面的每一个元素。

如果所说有误,还请指正,附上LIS的优化版本

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值