LeetCode689错误的贪心思路

题目是找3个长度为k的不重叠的子数组,和最大。
错误思路:
一开始理解成不重合,只要有一个不同就是不同的子数组。所以先用滑动窗口生成了所有长度为k的子数组的和,选和最大的前3个。
后来发现是不重叠,想用贪心,先选和最大的子区间,然后选不重叠的和最大的。知道这样不一定保证最优解,尝试选前10大的子区间,再从比它小的子区间里选不重叠的最大的。
代码如下

    private boolean chongDie(int b, List<Integer> a, int k) {
        for (int t : a) {
            if (Math.abs(b - t) < k) {
                return true;
            }
        }
        return false;
    }

    public int[] maxSumOfThreeSubarrays2(int[] nums, int k) {
        long cur = 0L;
        List<Pair<Long, Integer>> list = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            cur += nums[i];
        }
        list.add(new Pair<>(cur, 0));
        for (int i = k; i < nums.length; i++) {
            cur -= nums[i - k];
            cur += nums[i];
            list.add(new Pair<>(cur, i - k + 1));
        }
        System.out.println(list);
        list.sort(new Comparator<Pair<Long, Integer>>() {
            @Override
            public int compare(Pair<Long, Integer> o1, Pair<Long, Integer> o2) {
                if (o1.getKey().equals(o2.getKey())) {
                    if (o1.getValue() < o2.getValue()) {
                        return -1;
                    }
                } else if (o1.getKey() < o2.getKey()) {
                    return 1;
                } else if (o1.getKey() > o2.getKey()) {
                    return -1;
                }
                return 0;
            }
        });
        System.out.println(list);
        long sum = 0L;
        int[] ans = new int[3];
        for (int st = 0; st < Math.min(10, list.size()); st++) {
            cur = 0L;
            List<Integer> res = new ArrayList<>();
            res.add(list.get(st).getValue());
            cur += list.get(st).getKey();
            for (int i = st + 1; i < list.size(); i++) {
                if (!chongDie(list.get(i).getValue(), res, k)) {
                    cur += list.get(i).getKey();
                    res.add(list.get(i).getValue());
                    if (res.size() == 3) {
                        break;
                    }
                }
            }
            if (cur > sum) {
                Collections.sort(res);
                for (int i = 0; i < 3; i++) {
                    ans[i] = res.get(i);
                }
                sum = cur;
            }
        }
        return ans;
    }

对于输入

[17,7,19,11,1,19,17,6,13,18,2,7,12,16,16,18,9,3,19,5]
6

我的输出为

[0,6,12]

正确的输出是

[0,6,13]

分析一下,长度为k的子区间如下:

[74=0, 74=1, 73=2, 67=3, 74=4, 75=5, 63=6, 58=7, 68=8, 71=9, 71=10, 78=11, 74=12, 81=13, 70=14]
[81=13, 78=11, 75=5, 74=0, 74=1, 74=4, 74=12, 73=2, 71=9, 71=10, 70=14, 68=8, 67=3, 63=6, 58=7]

我的程序没有选13,它选的第一个最长的是12。
因为选13,后面选的还是贪心,最终选的是13、5,还是不能保证最优解。所以我的程序选13的结果没有答案的优。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值