问题描述
给定 1 到 9 共 9 个数字,随机将九个数字分成多组,按顺序从每组中任意取出一个数字组成一个新的数字,使得新组成的数字每位数字相加之和为偶数,求共有多少种组合方法。具体请配合样例理解。
思路
好久没有用过搜索做题了,今天偶然下遇到了这个题目,由于题目的输入限定在九个数字,所以深搜不用担心时间复杂度的问题,算是一个简简单单的题目
简单点说这题就是要求 从分好的数字组中每个里面取一个数字,加起来是偶数 的方案个数,刚开始我还在想有没有什么多项式算法可以快速解决这题,想的时候发现输入固定是9,那么也不用考虑时间复杂度了,直接上dfs,正好也有段时间没有用过了
这个问题的核心是从分好的数字组中每个里面取一个数字,使得加起来的结果是偶数。首先,将数字转换成字符串的操作是一个很巧妙的预处理步骤。这样做的好处在于,后续在取数的时候可以更加方便地进行操作。将原本的数字数组转换成字符串数组后,就为后续的枚举和搜索奠定了基础。
定义一个下标变量来表示当前是第几个数字组,这个变量在整个搜索过程中起到了关键的引导作用。每次枚举数字组中的每个数字时,可以将其累加到一个变量中,同时向后进行搜索。这样的过程可以通过递归的方式来实现。在递归的每一层,都代表着从一个数字组中选择一个数字的决策。
从第一个数字组开始,遍历其中的每个数字。选择一个数字后,将其累加到总和变量中,然后进入下一个数字组进行同样的操作。当遍历完所有的数字组后,检查总和是否为偶数。如果是偶数,则说明找到了一种满足条件的方案,方案个数加一。如果不是偶数,则继续回溯,尝试其他的数字组合。
在实现时,需要注意边界条件的处理。当遍历到最后一个数字组时,要注意判断总和的奇偶性。同时,为了避免重复计算,可以使用一些数据结构来记录已经搜索过的状态,提高搜索效率。
偶尔直接暴力深搜还是很爽的,具体代码如下
代码
public class Main {
public static int solution(int[] numbers) {
int len=numbers.length;
String[] nums=new String[len];
//将数字转化为字符串方便深搜处理
for(int i=0;i<len;i++){
nums[i]=String.valueOf(numbers[i]);
}
return dfs(nums,0,0);
}
public static int dfs(String[] numbers,int index,int sum){
//如果都取过了,判断是否是偶数
if(index==numbers.length){
if(sum%2==0)
{
return 1;
}
return 0;
}
int ans=0;
//对当前数字依次取每个数字
for(int i=0;i<numbers[index].length();i++){
int k=numbers[index].charAt(i)-'0';
//到下一个数字组中取数字
ans+=dfs(numbers, index+1, sum+k);
}
return ans;
}
public static void main(String[] args) {
System.out.println(solution(new int[]{123, 456, 789}) ==14);
System.out.println(solution(new int[]{123456789}) ==4);
System.out.println(solution(new int[]{14329, 7568})==10 );
}
}