问题描述:
小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。
numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。 例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369。
测试样例
样例1:
输入:numbers = [123, 456, 789]
输出:14
样例2:
输入:numbers = [123456789]
输出:4
样例3:
输入:numbers = [14329, 7568]
输出:10
我的思路如下:
以样例1 numbers=[123,456,789]为例,
首先选出符合条件的奇偶排列组合(这里用0-偶数,1-奇数)
000
001
010
011
100
101
110
111
这8种组合,我们知道只有一个整数序列中奇数的个数为偶数个时,其和才为偶数,
用01表示就更好判断了,直接求这三个数之和是不是偶数即可,然后挑选出符合的奇偶排列存起来。
再分别统计每个整数序列中偶数和奇数数字的个数即可,我用了一个自定义的getNumsOfOddAndEven方法返回该列表,它长这样:
要求的结果就是上述所有合格奇偶排列对应的组合数之和。
还有一个问题就是如何提取出上述奇偶排列中对应的数字? 这里我用的是循环按位与的操作,j代表移位的位数
for i in range(2**n):
sum=0
for j in range(n):
sum+=((i&(1<<j))!=0)
if sum%2==0:
res.append(i)
这样就大功告成了 完整代码如下:
def solution(numbers):
def getNumsOfOddAndEven(a):
final_ans=[]
for x in a:
ans=[0,0]
str_x=str(x)
for y in str_x:
if(int(y)%2==0):
ans[0]=ans[0]+1
else:
ans[1]=ans[1]+1
final_ans.append(ans)
return final_ans
n=len(numbers)
arr=getNumsOfOddAndEven(numbers)
res=[] #存储可行奇偶排列,0代表偶数,1代表奇数
for i in range(2**n):
sum=0
for j in range(n):
sum+=((i&(1<<j))!=0)
if sum%2==0:
res.append(i)
num=0
for i in res:
acc=1
for j in range(n):
flag=((i&(1<<j))!=0)
acc*=arr[j][flag]
num+=acc
return num
By the way,这里有个小坑,就是按位与(&)的结果判断不要写==1,我排查了好多遍,最后还是在Marscode的帮助下才找到的,大家要把AI工具用起来!
文章排版不太好,请多多见谅!