article / aiznoyer

算法

2.1 最长递归子序列

java
    public int lengthOfLIS(int[] nums) {
        // 初始化dp数组为1
        int[] dp = new int[nums.length];
        Arrays.fill(dp,1);
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < i; j++) {
                if(nums[i] > nums[j])
                    dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }

        int res = 0;
        for (int i = 0; i < dp.length; i++) {
            res = Math.max(res, dp[i]);
        }
        return res;
    }

2.2 信封嵌套

java
    public int maxEnvelopes (int[][] envelopes) {
        int n = envelopes.length;
        // 重写排序规则
        Arrays.sort(envelopes, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                // 按照第一个元素递增、相同情况下第二个元素递减排序
                return o1[0] == o2[0] ? o2[1] - o1[1] : o1[0] - o2[0];
            }
        });

        int[] height = new int[n];
        for (int i = 0; i < n; i++) {
            // 第一个元素有序,第二个元素无序,寻找最长递增子序列
            height[i] = envelopes[i][1];
        }
        return lengthOfLIS(height);
    }

2.3 最大子数组

java
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        if (n == 0) return 0;
        int[] dp = new int[n];

        dp[0] = nums[0];
        for (int i = 1; i < n; i++) {
            // 即使有负数也不影响,新的正数发现补不回前面的缺口就会断尾
            dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);
        }
        int res = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++) {
            res = Math.max(res, dp[i]);
        }
        return res;
    }
空间优化
java
    public int maxSubArray(int[] nums) {
        int n = nums.length;
        if (n == 0) return 0;
        int dp_0 = nums[0];
        // 化数组为两个数滚动
        int dp_1 = 0;
        int res = dp_0;

        for (int i = 1; i < n; i++) {
            dp_1 = Math.max(nums[i], nums[i] + dp_0);
            dp_0 = dp_1;
            // 直接比较减少循环
            res = Math.max(res, dp_1);
        }
        
        return res;
    }