LeetCode--368--medium--LargestDivisibleSubset

package com.app.main.LeetCode.dynamic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 368
 *
 * medium
 *
 * https://leetcode.com/problems/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.
 *
 * 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]
 *
 *
 * Created with IDEA
 * author:Dingsheng Huang
 * Date:2020/1/14
 * Time:下午3:32
 */
public class LargestDivisibleSubset {

    private List<Integer> result = new ArrayList<>();
    public List<Integer> largestDivisibleSubset(int[] nums) {
        if (nums.length == 0) {
            return result;
        }
        process(nums, new ArrayList<>(), 0);

        return result;
    }

    private void process(int[] nums, List<Integer> path, int start) {

        // prunning
        if ((nums.length - start + path.size()) <= result.size()) {
            return;
        }

        if (path.size() > result.size()) {
            result.clear();
            result.addAll(path);
        }

        if (start > nums.length - 1) {
            return;
        }

        for (int i = start; i < nums.length; i++) {
            // check nums[i]
            if (!check(nums, i, path)) {
                continue;
            }
            path.add(nums[i]);
            process(nums, path, i + 1);
            // backtrack
            path.remove(path.size() - 1);
        }
    }

    private boolean check(int[] nums, int i, List<Integer> list) {
        for (int k : list) {
            if (nums[i] % k != 0 && k % nums[i] != 0) {
                return false;
            }
        }
        return true;
    }


    // incorrect dp, something wrong, corner case
    public List<Integer> largestDivisibleSubset2(int[] nums) {

        List<Integer> result = new ArrayList<>();
        if (nums.length == 0) {
            return result;
        }
        int[][] matrix = new int[nums.length][nums.length];
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums.length; j++) {
                if (nums[i] % nums[j] == 0 || nums[j] % nums[i] == 0) {
                    matrix[i][j] = 1;
                    matrix[j][i] = 1;
                }
            }
        }
        // find max square
        int x = 0;
        int y = 0;
        int max = 0;
        int[][] dp = new int[matrix.length + 1][matrix.length + 1];
        for (int i = 1; i < dp.length; i++) {
            for (int j = 1; j < dp[0].length; j++) {
                if (matrix[i - 1][j - 1] == 1) {
                    dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
                    if (dp[i][j] > max) {
                        x = i;
                        y = j;
                        max = dp[i][j];
                    }
                }
            }
        }
        if (max == 0) {
            return result;
        }
        x = x > y ? x : y;
        x--;
        while (max > 0) {
            result.add(nums[x]);
            x--;
            max--;
        }
        return result;
    }


    // correct dp
    public List<Integer> largestDivisibleSubset3(int[] nums) {
        List<Integer> result = new ArrayList<>();
        if (nums.length == 0) {
            return result;
        }
        Arrays.sort(nums);
        int[] dp = new int[nums.length];
        int[] cache = new int[nums.length];
        dp[0] = 0;
        cache[0] = 0;
        int max = 0;
        int idx = 0;
        for (int i = 1; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if (nums[i] % nums[j] == 0) {
                    if (dp[i] < dp[j] + 1) {
                        dp[i] = dp[j] + 1;
                        cache[i] = j;
                    }
                    if (dp[i] > max) {
                        max = dp[i];
                        idx = i;
                    }
                }
            }
        }
        // backtrack
        result.add(nums[idx]);
        while (max > 0) {
            int tmp = cache[idx];
            result.add(nums[tmp]);
            idx = tmp;
            max--;
        }
        return result;
    }




    public static void main(String[] args) {
        System.out.println(2 % 1);
    }
}
发布了187 篇原创文章 · 获赞 26 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/huangdingsheng/article/details/103978152