LeetCode368 Largest Divisible Subset
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.
Input: [1,2,3]
Output: [1,2] (of course, [1,3] will also be ok)
and this is a dp problem, that’s something I did not expected at all.
the dp solution is essentially check every possible pair, but in a more effective way.
first, we need to presort the original array, why? because for every value1<value2, there is no way for value1 % value2==0
and then, we initialize two arrays, the first array called dp, which has the same length as original array. and dp[i] means the longest divisble subset of nums[0:i], and this length must contains the nums[i], and that’s why we need to initialize dp with 1. and the second array is called solution, and this will keep track of the path of our final result, so solution[i]=j means the next path node before current node will be nums[j]. and we will initialize solution with all values -1, so that mean when we backtracking the path, if we meet solution[i] is -1, then that means we finished.
class Solution {
public List<Integer> largestDivisibleSubset(int[] nums) {
List<Integer> res = new ArrayList<>();
if (nums == null || nums.length == 0) return res;
//why do we have to presort? because for every value1<value2, there is no way for value1 % value2==0
Arrays.sort(nums);
int[] dp = new int[nums.length]; //dp[i] means for subarray nums[0:i], the largest if we contains nums[i] in this subset
int[] solution = new int[nums.length]; //solution array shows a the result path, so solution[i] indicates the index of next node in original array
Arrays.fill(dp, 1);
Arrays.fill(solution, -1); //we have to initial it as -1 instead of 0 because -1 is definatly tells us, now it's over
int ans = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] % nums[j] == 0 && dp[i] < dp[j] + 1) { //this place is so important! only we need to update dp[i] and solution[i] when we have to! solution[i] store the next step is to j. and when we have a longer path will we update dp[i]
dp[i] = dp[j] + 1; //the length + 1
solution[i] = j;
}
}
if (dp[i] > dp[ans]) ans = i; //ans indicates the largest element's index of dp array
}
for (int i = ans; i != -1; i = solution[i]) { //starting from the last position, which is ans, until we meet the -1,which means the end of our path. and each time i moves to solution[i]
res.add(0, nums[i]); //add them, we don't have to add it to head, it's just for better look
}
return res;
}
}

浙公网安备 33010602011771号