实现子数组和绝对值差最小 - Objective-C

背包问题求解
本文介绍了一种解决类似背包问题的方法,特别关注数组全为正整数和0的情况。通过求和与递推的方式找到最接近目标值的子数组,最终得到两个子数组,其和的绝对差最小。

类似于背包问题,前提条件是数组全是正整数和0,先求和Sum,再从子数组中找出接近Sum/2的子数组

@interface TempState : NSObject

@property (nonatomic,assign) int iIdx;
@property (nonatomic,assign) int jIdx;

@end

@implementation TempState

@end

 

- (void)getSubArryMinABS{

    // 输入
    NSMutableArray *inputArry = [NSMutableArray arrayWithObjects:@"2",@"4",@"5",@"6",@"7" ,nil];
    NSLog(@"inputArry:%@",inputArry);

    // 输出
    NSMutableArray *outputArry = [NSMutableArray arrayWithCapacity:10];

    // 保存对应i,j数组元素的istrue状态
    NSMutableArray<TempState *> *tempStateArry = [NSMutableArray<TempState *> arrayWithCapacity:10];

    // 可根据实际情况扩容,如果做成通用,建议取count*1000,防止越界错误
    NSMutableArray *dpArry = [NSMutableArray arrayWithCapacity:20];
    for (int i = 0; i< 20; i++) {
        [dpArry addObject:@"0"];
    }

    __block NSInteger orginSum = 0;
    [inputArry enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        orginSum += [obj integerValue];
    }];

    int halfSum = (int)orginSum/2;

    for (int i = 0 ; i< inputArry.count; i++) {

        for (int j = halfSum; j >= [inputArry[i] intValue]; j--) {

            if ([dpArry[j] intValue] < [dpArry[j-[inputArry[i] intValue]] intValue] + [inputArry[i] intValue]) {

                dpArry[j] = [NSString stringWithFormat:@"%d",[dpArry[j-[inputArry[i] intValue]] intValue] + [inputArry[i] intValue]];

                TempState *temp = [[TempState alloc] init];
                temp.iIdx = i;
                temp.jIdx = j;
                [tempStateArry addObject:temp];
            }
        }
    }

    NSLog(@"dpArry:%@",dpArry);

    NSLog(@"tempStateArry:%@",tempStateArry);

    __block int jdx = halfSum;

    for (int index = (int)inputArry.count - 1 ; index >= 0; index --) {
        // [4 12]
        // [3 12]  j = 12 - 6 = 6  inputArry[3] = 6
        // [2 6]
        // [1 6]   j = 6 - 4 = 2   inputArry[1] = 4
        // [0 2]   j = 2 - 2 = 0   inputArry[0] = 2
        [tempStateArry enumerateObjectsUsingBlock:^(TempState * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

            TempState *temp = tempStateArry[idx];
            NSLog(@"index:%d & temp.iIdx:%d & temp.iIdx:%d",index,temp.iIdx,temp.jIdx);

            if (index == temp.iIdx && jdx == temp.jIdx) {
                NSLog(@"temp.iIdx:%d & temp.iIdx:%d & inputArry[idx]:%@",temp.iIdx,temp.jIdx,inputArry[index]);
                [outputArry addObject:inputArry[index]];
                jdx -= [inputArry[index] integerValue];
                NSLog(@"jdx:%d",jdx);
                *stop = YES;
            }
        }];
    }
    NSLog(@"最后结果outputArry:%@",_outputArry);
}
最后结果:
【246】 【5,7】

转载于:https://www.cnblogs.com/beckwang0912/p/8176425.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值