首页 > 基础资料 博客日记

hot100之动态规划下

2025-06-25 13:30:02基础资料围观10

文章hot100之动态规划下分享给大家,欢迎收藏Java资料网,专注分享技术知识

最长递增子序列(300)

class Solution {
    public int lengthOfLIS(int[] nums) {
        int res = 1;
        for(int num : nums){
            int idx = findLarge(nums, res, num);
            nums[idx] = num;
            if (idx == res) res++;   
        }
        
        return res;
    }

    private int findLarge(int[] nums, int rig, int target){
        int lef = -1;
        while (lef+1 < rig){
            int mid = (lef + rig) / 2;
            if (nums[mid] < target){
                lef = mid;
            }else rig = mid;
        }

        return rig;
    }
}
  • 分析

维护一个最小递增array(子序列)通过二分查找筛除坏值(比新插入值大)

利用二分查找优化查询

乘积的最大子数组(152)

class Solution {
    public int maxProduct(int[] nums) {
        int n = nums.length;
        int[] postive_dp = new int [n];
        int[] negative_dp = new int [n];

        postive_dp[0] = negative_dp[0] = nums[0];
        for(int i = 1; i < n; i++){
            postive_dp[i] =  max(postive_dp[i-1] * nums[i], negative_dp[i-1] * nums[i], nums[i]);
            negative_dp[i] = min(postive_dp[i-1] * nums[i], negative_dp[i-1] * nums[i], nums[i]);
        }
        
        int res = Integer.MIN_VALUE;
        for (int postive_num : postive_dp){
            res = Math.max(res, postive_num);
        }
        return res;
    }

    private int max(int val1, int val2, int val3){
        val2 = Math.max(val2, val3);
        return Math.max(val1, val2);
    }

    private int min(int val1, int val2, int val3){
        val2 = Math.min(val2, val3);
        return Math.min(val1, val2);
    }
}
  • 分析

因为num有<正,负>两种状态,即使前值算出来很小 但通过乘负数可以将大局逆转吧

所以维护最大正数和最小负数两个dp,都是潜力

同样也可以优化内存, 因为只依赖前一个状态

分割等和子集(416)

class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int num: nums){
            sum += num;
        }
        if (sum % 2 != 0) return false;

        int target = sum / 2;
        boolean[] dp = new boolean[target+1];
        dp[0] = true;
        for (int num : nums){
            for (int subSum = target; subSum >= num; subSum--){
                dp[subSum] |= dp[subSum - num];
                if (dp[target]) return true;
            }
        }
        return false;
    }
}
  • 分析

背包问题

最长有效括号(32)

class Solution {
    public int longestValidParentheses(String s) {
        int n = s.length();
        Deque<Integer> stack = new ArrayDeque<>();
        stack.push(-1); // 避免第一个数值是左括号, 无值弹出
        int res = 0;

        for (int i = 0; i < n; i++){
            if (s.charAt(i) == '('){
                stack.push(i);
            }else{
                stack.pop();
                if (stack.isEmpty()){
                    stack.push(i);
                }else{
                    res = Math.max(res, i - stack.peek());
                }
            }
        }

        return res;
    }
}
  • 分析

没什么好想法,就用栈了

java 里栈的优化似乎不好,不如双端队列


文章来源:https://www.cnblogs.com/many-bucket/p/18947833
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云