力扣爆刷第100天之hot100五连刷86-90

力扣爆刷第100天之hot100五连刷86-90

文章目录

      • 力扣爆刷第100天之hot100五连刷86-90
      • [一、139. 单词拆分](#一、139. 单词拆分)
      • [二、300. 最长递增子序列](#二、300. 最长递增子序列)
      • [三、152. 乘积最大子数组](#三、152. 乘积最大子数组)
      • [四、416. 分割等和子集](#四、416. 分割等和子集)
      • [五、32. 最长有效括号](#五、32. 最长有效括号)

一、139. 单词拆分

题目链接:https://leetcode.cn/problems/word-break/description/?envType=study-plan-v2\&envId=top-100-liked

思路:定义dp[i]表示字符串s[0, i]可以被拼接出,那么如果要推导出当前s[0,i]可以被拼出,只需要,s[0, i-word.length]可以被拼出,且s[i-word.length] == w,即可推出,此即为递推公式。

java 复制代码
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;
        for(int i = 1; i < dp.length; i++) {
            for(String word : wordDict) {
                if(i < word.length() || dp[i] || !dp[i-word.length()]) continue;
                dp[i] = isTrue(s, word, i);
            }
        }
        return dp[s.length()];
    }
    
    boolean isTrue(String s, String word, int index) {
        int i = index - word.length(), j = 0;
        while(i < index) {
            if(s.charAt(i) != word.charAt(j)) return false;
            i++;
            j++;
        }
        return true;
    }
}

二、300. 最长递增子序列

题目链接:https://leetcode.cn/problems/longest-increasing-subsequence/description/?envType=study-plan-v2\&envId=top-100-liked

思路:定义dp[i]表示区间[0, i]以nums[i]为结尾的最长递增子序列的长度,那么如果nums[i] > nums[j],故 dp[i] = Math.max(dp[i], dp[j]+1);

java 复制代码
class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        Arrays.fill(dp, 1);
        int max = 1;
        for(int i = 1; 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);
                }
            }
            max = Math.max(max, dp[i]);
        }
        return max;
    }
}

三、152. 乘积最大子数组

题目链接:https://leetcode.cn/problems/maximum-product-subarray/description/?envType=study-plan-v2\&envId=top-100-liked

思路:求最长乘积子数组,由于元素有负数存在,我们求每一个位置的最大值,该最大值的并不一定依赖的是前一个位置的最大值,也可能是前一个位置的最小值,所以要用两个数组记录分表记录最大和最小值,在求最大值的时候,dp[i] = max(前一个位置的最大值 * 当前元素 , 当前元素, 前一个位置的最小值 * 当前元素)。每一个dp[i]由三种装填推出。

java 复制代码
class Solution {
    public int maxProduct(int[] nums) {
        int[] dpMax = new int[nums.length];
        int[] dpMin = new int[nums.length];
        dpMax[0] = nums[0];
        dpMin[0] = nums[0];
        int max = nums[0];
        for(int i = 1; i < nums.length; i++) {
            dpMax[i] = Math.max(dpMax[i-1] * nums[i], Math.max(nums[i], dpMin[i-1] * nums[i]));
            dpMin[i] = Math.min(dpMin[i-1] * nums[i], Math.min(nums[i], dpMax[i-1] * nums[i]));            
        }
        for(int i = 1; i < nums.length; i++) {
            max = Math.max(max, dpMax[i]);
        }
        return max;
    }
}

四、416. 分割等和子集

题目链接:https://leetcode.cn/problems/partition-equal-subset-sum/description/?envType=study-plan-v2\&envId=top-100-liked

思路:划分等和子集是背包题的一种变体,只要总和不是奇数就可以划分,然后把和的一般作为背包容量,然后物品在外,背包在内,背包逆序。

java 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for(int v : nums) sum += v;
        if(sum % 2 == 1) return false;
        sum = sum / 2;
        int[] dp = new int[sum+1];
        for(int i = 0; i < nums.length; i++) {
            for(int j = sum; j >= nums[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j-nums[i]] + nums[i]);
            }
        }
        return dp[sum] == sum;
    }
}

五、32. 最长有效括号

题目链接:https://leetcode.cn/problems/longest-valid-parentheses/description/?envType=study-plan-v2\&envId=top-100-liked

思路:使用动态规划做时间超了,可以使用栈做。

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        if(s.length() == 0) return 0;
        int[] dp = new int[s.length()];
        int max = 0;
        for(int i = 1; i < s.length(); i++) {
            for(int j = 0; j < i; j++) {
                if(isTrue(s, j, i)) {
                    dp[i] = i-j+1;
                    break;
                }
            }
            max = Math.max(max, dp[i]);
        }
        return max;
    }

    boolean isTrue(String s, int left, int right) {
        int num = 0;
        while(left <= right) {
            if(s.charAt(left++) == '(') {
                num++;
            }else{
                num--;
            }
            if(num < 0) return false;
        }
        return num == 0;
    }
}

使用栈:

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        int maxans = 0;
        int[] dp = new int[s.length()];
        for (int i = 1; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                if (s.charAt(i - 1) == '(') {
                    dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
                } else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
                    dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
                }
                maxans = Math.max(maxans, dp[i]);
            }
        }
        return maxans;
    }
}
相关推荐
棱镜Coding19 分钟前
LeetCode-Hot100 30.两两交换链表中的节点
算法·leetcode·链表
虎头金猫21 分钟前
内网导航站 “出圈”!用 cpolar 解锁 Dashy 远程访问新玩法
java·c++·python·程序人生·职场和发展·php·程序员创富
2301_7903009624 分钟前
C++与量子计算模拟
开发语言·c++·算法
汽车仪器仪表相关领域34 分钟前
经典指针+瞬态追踪:MTX-A模拟废气温度(EGT)计 改装/赛车/柴油车排气温度监测实战全解
大数据·功能测试·算法·机器学习·可用性测试
如果你想拥有什么先让自己配得上拥有41 分钟前
斐波那契黄金分割自然界演化以及金融上的共振?
算法·金融
灰色小旋风43 分钟前
力扣第1题:两数之和(C++)
c++·算法
民乐团扒谱机1 小时前
机器学习 第二弹 和AI斗智斗勇 机器学习核心知识点全解析(GBDT/XGBoost/LightGBM/随机森林+调参方法)
算法·决策树·机器学习
智驱力人工智能1 小时前
实线变道检测 高架道路安全治理的工程化实践 隧道压实线监测方案 城市快速路压实线实时预警 压实线与车牌识别联动方案
人工智能·opencv·算法·安全·yolo·边缘计算
We་ct1 小时前
LeetCode 3. 无重复字符的最长子串:滑动窗口最优解演进与解析
前端·算法·leetcode·typescript
沉默-_-1 小时前
备战蓝桥杯--栈
数据结构·算法·力扣·