小鸡玩算法-力扣HOT100-动态规划(下)

一.单词拆分

问题概述:

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

思路:

一个字符串可不可以拼接,可以将其拆分成两部分看,如果前部分是可以拆分的并且剩下一部分刚好在wordDict当中,那这个字符串就是可以拼接的。

代码:

javascript 复制代码
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<String> worldSet=new HashSet<>(wordDict);
        int n=s.length()+1;

        boolean[] dp=new boolean[n];
        dp[0]=true;

        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){
                if(dp[j]&&worldSet.contains(s.substring(j,i))){
                    dp[i]=true;
                    break;
                }
            }
        }

        return dp[n-1];
    }
}

二.最长递增子序列

问题概述:

思路:

每个元素本身可以构成1个子序列,那dp[]初值都设为1。

那后面新加的nums[i]比前面nums[j]大就选nums[i]和nums[j]+1大的那个,

例如:nums=[10,1,2,5]

10 dp[0]=1

新加1 1<10 dp[1]=1

新加2 2<10 2>1 dp[2]=max(dp[1]+1,dp[2])

新加5 5<10 5>1 dp[3]=max(dp[1]+1,dp[3]) 5>2 dp[3]=max(dp[2]+1,dp[3])

代码:

java 复制代码
class Solution {
    public int lengthOfLIS(int[] nums) {
        int n=nums.length;

        int[] dp=new int[n];
        int maxn=1;

        for(int i=0;i<n;i++){
            dp[i]=1;
        }

        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){
                if(nums[i]>nums[j]){
                    dp[i]=Math.max(dp[j]+1,dp[i]);
                }
            }

            maxn=Math.max(maxn,dp[i]);

        }

        return maxn;
    }
} 

三.乘积最大子数组

问题概述:

思路:

新加一个nums[i],那此刻包含这个数的最大数要么就是正正 负负 本身得到的

代码:

java 复制代码
class Solution {
    public int maxProduct(int[] nums) {
       
        int max=nums[0];
        int min=nums[0];
        int res=nums[0];
        int n=nums.length;

        for(int i=1;i<n;i++){
            int tempmax=max;
            int tempmin=min;

            max=Math.max(nums[i],Math.max(tempmax*nums[i],tempmin*nums[i]));
            min=Math.min(nums[i],Math.min(tempmax*nums[i],tempmin*nums[i]));
            res=Math.max(res,max);
        }

        return res;      
    }
}

四.分割等和子集

问题概述:

给你一个 只包含正整数非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

思路:

就是看能不能凑成总数的一半,如果总数和为奇数则可以直接返回false了,如果为偶数进一步判断,dp[11]是否为true,因为所给的nums本身不是有序的,所以需要每个遍历,

num=1

dp[11]=dp[11]||dp[11-1]

dp[10]=dp[10]||dp[10-1]

...

dp[1]=dp[1]||dp[1-1]=true

此时只有dp[0]、dp[1]为true

num=5

dp[11]=dp[11]||dp[11-5]

dp[10]=dp[10]||dp[10-5]

...

dp[5]=dp[5]||dp[0]

此时dp[0]、dp[1]、dp[5]为true

num=11

dp[11]=dp[11]||dp[11-11] 为true 现在已结束,dp[0]、dp[1]、dp[5]、dp[11]为true

代码:

java 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        int sum=0;
        for(int num : nums){
            sum+=num;
        }

        if(sum%2==1){
            return false;
        }

        int target=sum/2;
        boolean[] dp=new boolean[target+1];
        dp[0]=true;

        for(int num:nums){
            for(int j=target;j>=num;j--){
                dp[j]=dp[j]||dp[j-num];
            }
        }

        return dp[target];
    }
}

五.最长有效括号

问题概述:

给你一个只包含 '('')' 的字符串,找出最长有效(格式正确且连续)括号 子串 的长度。

左右括号匹配,即每个左括号都有对应的右括号将其闭合的字符串是格式正确的,比如 "(()())"为6.

思路:

dp[i]表示以索引为i结尾的最长有效括号子串的长度。

①当结尾为'(',就是不合法的,就记0.

②当结尾为')', a.dp[i-1]为'(' :dp[i]=d[i-2]+2

b.dp[i-1]为')' : 需满足dp[i-dp[i-1]-1]=='('才能包起来,然后dp[i]=dp[i-1]+2+dp[i-dp[i-dp[i-1]-2]

注意:越界条件判断

代码:

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        int n=s.length();

        if(n<2){
            return 0;
        }

        int[] dp=new int[n];
        int max=0;

        for(int i=1;i<n;i++){
            if(s.charAt(i)==')'){
                if(s.charAt(i-1)=='('){
                    dp[i]=i-2>=0 ? dp[i-2]+2 : 2;
                }else if(s.charAt(i-1)==')'){
                    if(i-dp[i-1]-1>=0&&s.charAt(i-dp[i-1]-1)=='('){
                        dp[i]=i-dp[i-1]-2>=0 ? dp[i-1]+2+dp[i-dp[i-1]-2] : dp[i-1]+2;
                    }                      
                }
            }
            max=Math.max(max,dp[i]);
            
        }
        
        return max;
    }
} 
相关推荐
信奥胡老师4 小时前
B3968 [GESP202403 五级] 成绩排序
数据结构·算法
Hwang2524 小时前
Attention 机制 02 - Add&Norm 残差机制
算法
东风破_4 小时前
LeetCode 209 · 滑动窗口经典题型
算法
计算机安禾4 小时前
【c++面向对象编程】第48篇:Lambda表达式与std::function:OOP中的函数式编程
java·c++·算法
手写码匠5 小时前
【实战评测】华为云 MaaS 平台 DeepSeek 大模型推理服务 + Dify 一键部署全攻略
人工智能·深度学习·算法·aigc
咪饭只吃一小碗5 小时前
JS算法基础: 常用方法整理
算法·程序员
z200509305 小时前
今日算法(回溯算法)
数据结构·算法
毅炼6 小时前
今日LeetCode 摸鱼打卡
java·算法·leetcode
m0_629494736 小时前
LeetCode 热题 100-----28. 两数相加
数据结构·算法·leetcode·链表