第二十四天
1725 可以形成最大正方形的矩形数目
给你一个数组 rectangles ,其中 rectangles[i] = [li, wi] 表示第i个矩形的长度为li、宽度为 wi。
如果存在 k 同时满足 k <= li 和 k <= 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
}
}
本文探讨了如何通过优化算法解决两个问题:一是从矩形数组中找出能切出最大正方形边长的矩形数量,二是提供全排列的独特解决方案,避免重复。涉及的方法包括哈希集合、排序和递归策略。
634

被折叠的 条评论
为什么被折叠?



