leetcode刷题第24天——1725,47,39,40

第二十四天

1725 可以形成最大正方形的矩形数目

给你一个数组 rectangles ,其中 rectangles[i] = [li, wi] 表示第i个矩形的长度为li、宽度为 wi

如果存在 k 同时满足 k <= lik <= wi ,就可以将第i 个矩形切成边长为k 的正方形。例如,矩形 [4,6] 可以切成边长最大为 4的正方形。

maxLen 为可以从矩形数组 rectangles 切分得到的 最大正方形 的边长。

请你统计有多少个矩形能够切出边长为 maxLen 的正方形,并返回矩形 数目 。

方法

使用一个变量maxValue记录最大值,maxCount记录数量,遍历整个数组即可。

class Solution {
    public int countGoodRectangles(int[][] rectangles) {
        int maxCount = 0;
        int maxValue = Integer.MIN_VALUE;
        for (int i = 0; i < rectangles.length; ++i){
            int cmpValue = Math.min(rectangles[i][0], rectangles[i][1]);
            if (cmpValue == maxValue) maxCount++;
            else if (cmpValue > maxValue){
                maxCount = 1;
                maxValue = cmpValue;
            }
        }
        return maxCount;
    }
}

47 全排列 Ⅱ

给定一个可包含重复数字的序列 nums按任意顺序 返回所有不重复的全排列。

方法

由于不能存在重复的元素,使用一个哈希集合来维护序列的唯一性。

class Solution {
    public static List<Integer> aArray;
    public static List<List<Integer>> res;
    public static boolean[] isUsed;
    public static HashSet<ArrayList<Integer>> set;

    public List<List<Integer>> permuteUnique(int[] nums) {
        isUsed = new boolean[nums.length];
        set = new HashSet<>();
        res = new ArrayList<>();
        aArray = new ArrayList<>();
        permute(nums, 0);
        return res;
    }

    public static void permute(int[] nums, int depth){
        if (depth == nums.length){
            if (!set.contains(aArray)){
                set.add(new ArrayList<>(aArray));
                res.add(new ArrayList<>(aArray));
            }
            return;
        }
        for (int i = 0; i < nums.length; ++i){
            if (!isUsed[i]){
                isUsed[i] = true;
                aArray.add(nums[i]);
                permute(nums, depth + 1);
                isUsed[i] = false;
                aArray.remove(aArray.size() - 1);
            }
        }
    }
}

39 组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

方法

由于同一个数字可以不限制数量选取,对原有的组合算法稍作修改,当选取第i个位置上的数字时,可以判断一下当前的总和是否没有超过目标值,如果没有超过,在当前的递归层再继续递归

class Solution {
    public static List<List<Integer>> res;
    public static ArrayList<Integer> aArray;

    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        aArray = new ArrayList<>();
        res = new ArrayList<>();
        backTrace(candidates, target, 0);
        return res;
    }


    public static void backTrace(int[] nums,int target, int depth){
        if (target == 0){
            res.add(new ArrayList<>(aArray));
            return;
        }
        if (depth == nums.length) return;
        if (target - nums[depth] >= 0){ //如果满足条件 继续在当前层递归
            aArray.add(nums[depth]);
            backTrace(nums, target - nums[depth], depth);
            aArray.remove(aArray.size() - 1);//少选一个
        }
        backTrace(nums, target, depth + 1);//选下一个
    }
}

40 组合总和Ⅱ

给定一个候选人编号的集合 candidates和一个目标数 target,找出candidates中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次 。

**注意:**解集不能包含重复的组合。

方法

由于题目要求不能存在重复的集合,因此可以先将所有数字进行排序,这样就可以让重复的元素都放在相邻的位置上。对于重复的序列[a1,a2,a3],如果需要保证所选出来的子集没有重复,那么我们应当在不选元素a时,所有的元素a都不应该选择。为此,在组合算法的原有基础之上,加上一个参数choose,表示是否选择了上一个值。当我们遇到连续的相同值时,可以通过判断choose值来确定连续的相同值是否应该被选择。

class Solution {
    public static List<List<Integer>> res;
    public static ArrayList<Integer> aArray;

    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        aArray = new ArrayList<>();
        res = new ArrayList<>();
        Arrays.sort(candidates);
        backTrace(true, candidates, target, 0);
        return res;
    }


    public static void backTrace(boolean choose, int[] nums,int target, int depth){
        System.out.println(aArray);
        if (target == 0) {
            res.add(new ArrayList<>(aArray));
            return;
        }
        if (target < 0 || depth == nums.length) return;
        if (depth - 1 >= 0 && !choose && nums[depth - 1] == nums[depth]) {
            backTrace(false, nums, target, depth + 1);
            return;
        }//相邻的相同的值 如果上一个值没有被选 则当前值也不应该选 直接进入下一层递归层 然后返回即可
        aArray.add(nums[depth]);
        backTrace(true, nums, target - nums[depth], depth + 1);//选当前值 choose为true
        aArray.remove(aArray.size() - 1);
        backTrace(false, nums, target, depth + 1);//不选当前值 choose为false
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值