java机试题*:数组分组(按条件分组、动态规划两种思路、条件转化、【完整搜索使用循环可能会漏掉间隔组合的情况,需要使用递归动态规划场景来找出所有组合】)
描述
输入int型数组,询问该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),不是5的倍数也不是3的倍数能放在任意一组,可以将数组分为空数组,能满足以上条件,输出true;不满足时输出false。
本题含有多组样例输入。
数据范围:每个数组大小满足 1 \le n \le 50 \1≤n≤50 ,输入的数据大小满足 |val| \le 500 \∣val∣≤500
输入描述:
第一行是数据个数,第二行是输入的数据
输出描述:
返回true或者false
import java.util.ArrayList; import java.util.List; import java.util.Scanner; // 思路1:找到将ohter分给这两个组的所有情况,有一组和相等则满足条件,但是找出所有的随机组合不好实现。 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextInt()) { // 分别获取3组,5组,其他组相关信息 int num = in.nextInt(); int fiveSum = 0; int threeSum = 0; int sum = 0; List<Integer> other = new ArrayList<Integer>(); for (int i = 0; i < num; i++) { int temp = in.nextInt(); if(temp % 5 == 0) { fiveSum += temp; } else if(temp % 3 == 0) { threeSum += temp; } else { other.add(temp); } sum += temp; } // 获取是否满足条件 boolean ret = false; // 1.总和不是偶数必定不满足 if(sum % 2 != 0){ ret = false; // 2.其他组没有数时,3和5组各自和相等即可 } else if(other.size() == 0) { if(fiveSum == threeSum) { ret = true; } } else { //3. 其他组有数时,获取所有分组的和,使得分完组后满足,判断fiveSum == threeSum ret = getTarget(0,fiveSum, threeSum,other); } System.out.println(ret); } } /** * 获取所有分组的和,使得分完组后满足,fiveSum == threeSum */ public static boolean getTarget(int index, int fiveSum,int threeSum, List<Integer> other) {
// 终止条件,分组完成 if(index == other.size()) { return fiveSum == threeSum; } else { // 分两种情况:分给3组,分给5组 return getTarget(index + 1,fiveSum + other.get(index) ,threeSum, other) || getTarget(index + 1,fiveSum, threeSum + other.get(index), other); } } }
import java.util.ArrayList; import java.util.List; import java.util.Scanner; // 思路2:分完组后,两组和相等,则有:sum / 2 = arr1(分组后) = arr2(分组后),则sum必定是偶数 // 则,其他组中需要满足存在sum / 2 - arr1(分组前)的一个和。任意组合,能得到该数即可 // 或存在sum/2 - arr2(分组前),分组前,即,其他组中的数还没有分给3和5组。 // 这里使用思路2 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextInt()) { // 分别获取3组,5组,其他组相关信息 int num = in.nextInt(); int fiveSum = 0; int threeSum = 0; int sum = 0; List<Integer> other = new ArrayList<Integer>(); for (int i = 0; i < num; i++) { int temp = in.nextInt(); if(temp % 5 == 0) { fiveSum += temp; } else if(temp % 3 == 0) { threeSum += temp; } else { other.add(temp); } sum += temp; } // 获取是否满足条件 boolean ret = false; // 1.总和不是偶数必定不满足 if(sum % 2 != 0){ ret = false; // 2.其他组没有数时,3和5组各自和相等即可 } else if(other.size() == 0) { if(fiveSum == threeSum) { ret = true; } } else { //3. 其他组有数时,用下面的双循环逻辑不完整,会漏掉,间隔相加的和,故这样不能找到所有的和 // for (int i = 0; i < other.size(); i++) { // int targetNum = 0; // for (int j = i; j < other.size(); j++) { // targetNum += other.get(j); // if(sum / 2 - fiveSum == targetNum) { // ret = true; // break; // } // } // } // 其他组有数时,递归遍历出,是否某满足的和存在 ret = getTarget(0,sum / 2 - fiveSum,other); } System.out.println(ret); } } /** * 获取是否有满足条件的数 */ public static boolean getTarget(int index, int targetNum, List<Integer> other) { // 终止条件,递归完ohther。若,targetNum == 0,则满足条件 // (因为targetNum在递归中会不断剔除某位置的数,直到剔除到0,说明其他组中存在一个和targetNum = sum / 2 - fiveSum) if(index == other.size()) { return targetNum == 0; } else { // 有两种情况:使用index位置的数 + 不使用index位置的数 return getTarget(index + 1,targetNum - other.get(index),other) || getTarget(index + 1, targetNum,other); } } }
题目来源:牛客网
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示