繁体   English   中英

最长递增子序列,动态编程

[英]Longest Increasing Subsequence, Dynamic Programing

我有以下问题:

查找给定序列/数组的最长递增子序列。

换句话说,找到一个数组的子序列,其中该子序列的元素严格按升序排列,并且该子序列尽可能长。 该子序列不一定是连续的或唯一的。 在这种情况下,我们只关心最长的递增子序列的长度。

范例:

输入:[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15]输出:6顺序:[0,2,6,9, 13、15]或[0、4、6、9、11、15]或[0、4、6、9、13、15]

这是DP的问题,在记忆步骤中我确实有一些问题。 这是我的代码:

public int lis(final List<Integer> a) {
    return maxIncreasing(0, Integer.MIN_VALUE, a);
}
HashMap<Integer, Integer> memo = new HashMap<>();
private int maxIncreasing(int index, int lastElt, final List<Integer> a) {
    if(memo.containsKey(index)) return memo.get(index);
    // end?
    if(index >= a.size()) return 0;
    int weTake = Integer.MIN_VALUE;
    // can we take it?
    if(a.get(index) > lastElt) {
        // take it or don't
        weTake = maxIncreasing(index + 1, a.get(index), a) + 1;
    }
    int weDoNot = maxIncreasing(index + 1, lastElt, a);
    int max = Math.max(weTake, weDoNot);
    memo.put(index, max);
    return max;
}

如果没有备忘HashMap,我将得到正确的结果,但我不确定为什么这会给我错误的结果。

谢谢。

那是因为您没有照顾lastElt 基本上,根据lastElt值,给定index可以有多个解决方案。 因此,你必须有一个Key你的memo同时包含indexlastElt

您可以执行以下操作:

    class Key {
        final int index;
        final int lastEl;

        Key(int index, int lastEl) {
            this.index = index;
            this.lastEl = lastEl;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Key key = (Key) o;

            if (index != key.index) return false;
            return lastEl == key.lastEl;

        }

        @Override
        public int hashCode() {
            int result = index;
            result = 31 * result + lastEl;
            return result;
        }
    }

    public int lis(final List<Integer> a) {
        return maxIncreasing(0, Integer.MIN_VALUE, a);
    }
    HashMap<Key, Integer> memo = new HashMap<>();
    private int maxIncreasing(int index, int lastElt, final List<Integer> a) {
        Key key = new Key(index ,lastElt);
        if(memo.containsKey(key)) return memo.get(key);
        // end?
        if(index >= a.size()) return 0;
        int weTake = Integer.MIN_VALUE;
        // can we take it?
        if(a.get(index) > lastElt) {
            // take it or don't
            weTake = maxIncreasing(index + 1, a.get(index), a) + 1;
        }
        int weDoNot = maxIncreasing(index + 1, lastElt, a);
        int max = Math.max(weTake, weDoNot);
        memo.put(key, max);
        return max;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM