Python面试题,排列生成的解法,最优解答

 

有两个序列a,b, 大小都为n, 序列元素的值为任意整型数,无序;

 

要求:通过交换a,b中的[序列a元素的和]与[序列b元素的和]之间的差最小。

 

我的解答:

最后的解答结果都是我见到的测试方法,此方法本质上是穷举法,必然是最优解答。

 

在递归函数里保存列表is_used(用来保存某个元素是否已经用过了)的时候,一定要注意用copy.deepcopy.

不然保存的所有列表都是[0,0,0,.....], 因为如果不用前叙的方法的话, append()的是所有list的引用,而所有的这些引用指向的是同一个list对象,所以所有的子序列都一样,而这个序列最后返回到了初试状态,都是0,切记切记!

 

 

# it can be seen as  a computation problem,
# so use un-repeatible enumerate method to find the best result


import copy


# test suit
# au: thomas will lee, lzj, 

# new = [1, 2, 3, 4, 5, 6, 700, 800]  # my 97 91, better than 99

new = [93, 91, 90, 82, 81, 74, 74, 74, 74, 68]

# store_dict = {min_difference: []}

# new = [1, 50, 90, 100, 10000, 10001]  # my 38, 38, worth than 40


# new = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # 1 , 1 ;1



# new = [1, 1, 2, 3, 29, 30, 210, 232, 12311, 12312] # abs(-19)= 19 ,17, better than 21
# min_custom_enumerate(new)


sub_len = len(new) / 2
# to enumerate numbers in the list new
# a_iter = [0 for i in xrange(sub_len)]
# record whether one element is used
is_used = [0 for i in xrange(len(new))]

median = len(new) / 2
    # use a list as a stack to store all scenarios
    # sf = open('store_file','w') 
    # min_custom_enumerate_recursive(0)

all_list = []

def min_custom_enumerate_recursive(k):
    if k == sub_len:
        all_list.append(copy.deepcopy(is_used)) 
        # min_recode()
        # all_list.append(a_iter)
        # sf.write(str(is_used))
        # all_list += is_used
    else:
        for i in xrange(len(new)):
            if not is_used[i]:
                # all_list.append(is_used)
                # a_iter[k] = new[i]
                is_used[i] = 1  # used
                min_custom_enumerate_recursive(k + 1)
                is_used[i] = 0  # after the recursion backtracks


def solve():    
    # len(new) is always even
    min_custom_enumerate_recursive(0)    
        # with open("store_file") as ff:
    # # c = 1
    #      str(ff.readlines())

    # print all_list
    min_difference = abs(sum(new[:median]) - sum(new[median:]))
    # min_difference = 1000000000000
    all_list_len = len(all_list)
    final_a = []
    final_b = []
    for line in all_list:
        line_a = [new[i] for i in xrange(len(line)) if line[i] == 1]
        line_b = [new[i] for i in xrange(len(line)) if line[i] == 0]
        # print 'line_a',line_a
        # print 'line_b',line_b

        # print line_b
        line_a_sum = sum(line_a)
        line_b_sum = sum(line_b)
        new_difference = abs(line_a_sum - line_b_sum)
        if new_difference < min_difference:
            min_difference = new_difference
            final_a = copy.deepcopy(line_a)
            final_b = copy.deepcopy(line_b)
    print 'smallest value is', min_difference
    print 'a', final_a
    print 'b', final_b

solve()

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值