hot100(81-90)

  1. 爬楼梯
    用dp数组记录到达每个阶梯的方案数
java 复制代码
class Solution {
    public int climbStairs(int n) {
        int[] dp=new int[n+1];
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<=n;i++){
            dp[i]=dp[i-1]+dp[i-2];
        }
        return dp[n];
    }
}
  1. 杨辉三角
    模拟,注意头尾为1,中间是按照上一层两个值算出的,只要是算的值,保证加数和被加数存在
java 复制代码
class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> list=new ArrayList<>();
        for(int i=0;i<numRows;i++){
            List<Integer> temp=new ArrayList<>();
            for(int j=0;j<=i;j++){
                if(j==0||j==i) temp.add(1);
                else temp.add(list.get(i-1).get(j-1)+list.get(i-1).get(j));
            }
            list.add(temp);
        }
        return list;
    }
}
  1. 打家劫舍
    维护一个当前最大金额
java 复制代码
class Solution {
    public int rob(int[] nums) {
        if(nums.length==1) return nums[0];
        int[] dp=new int[nums.length];
        dp[0]=nums[0];
        dp[1]=Math.max(nums[0],nums[1]);
        for(int i=2;i<nums.length;i++){
            dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
        }
        return dp[nums.length-1];
    }
}
  1. 完全平方数
java 复制代码
class Solution {
    public int numSquares(int n) {
        int[] dp=new int[n+1];
        Arrays.fill(dp,10001);
        dp[0]=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j*j<=i;j++){
                dp[i]=Math.min(dp[i-j*j]+1,dp[i]);
            }
        }
        return dp[n];
    }
}
  1. 零钱兑换
    排序后,如果大于当前值,直接break
    初始化为amount+1,可以防止越界(一定记住)
    记得dp[0]=0
    通过amount+1可以保证,凑不齐时,加到我这里一定不是最小值
java 复制代码
class Solution {
    public int coinChange(int[] coins, int amount) {
        Arrays.sort(coins);
        int[] dp=new int[amount+1];
        Arrays.fill(dp,amount+1);
        dp[0]=0;
        for(int i=1;i<=amount;i++){
            for(int j=0;j<coins.length;j++){
                if(coins[j]>i) break;
                dp[i]=Math.min(dp[i],dp[i-coins[j]]+1);
            }
        }
        return dp[amount]==amount+1?-1:dp[amount];
    }
}
  1. 单词拆分
    从头枚举字符串长度,判断是否存在单词满足该字符串,满足就true,开始下一个字符串
    优化点,二重循环枚举字符串头,用set找适合的单词(相比遍历单词数组更快)
java 复制代码
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        Set<String> set=new HashSet<>();
        for(int i=0;i<wordDict.size();i++) set.add(wordDict.get(i));
        int n=s.length();
        boolean[] dp=new boolean[n+1];
        dp[0]=true;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=i;j++){
                if(set.contains(s.substring(j-1,i))&&dp[j-1]){
                    dp[i]=true;
                    break;
                }
            }
        }
        return dp[n];
    }
}
  1. 最长递增子序列
    维护一个最长序列
    每次大于我最大值,或者为空我直接放在末尾,更新最大值
    否则找到第一个大于等于我的值覆盖,方便后续链路找最大值
java 复制代码
class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp=new int[nums.length];
        int end=-1;
        for(int i=0;i<nums.length;i++){
            if(end==-1||dp[end]<nums[i]) dp[++end]=nums[i];
            else{
                find(nums[i],dp,end);
            }
        }
        return end+1;
    }

    public void find(int target,int[] dp,int end){
        int l=-1,r=end+1;
        while(l+1!=r){
            int mid=l+(r-l)/2;
            int num=dp[mid];
            if(num>=target){
                r=mid;
            }else l=mid;
        }
        dp[r]=target;
    }
}
  1. 乘积最大子数组
    注意动态规划的空间压缩一般是当前状态只依赖前一个状态
java 复制代码
class Solution {
    public int maxProduct(int[] nums) {
        int res=nums[0];
        int maxVal=nums[0];
        int minVal=nums[0];
        for(int i=1;i<nums.length;i++){
            int max=maxVal;
            maxVal=Math.max(nums[i],Math.max(nums[i]*maxVal,nums[i]*minVal));
            if(maxVal>res) res=maxVal;
            minVal=Math.min(nums[i],Math.min(nums[i]*max,nums[i]*minVal));
        }
        return res;
    }
}
  1. 分割等和子集
    就是找到是否存在子集的和为总和一半
    总和为奇数或者最大值大于总和一半直接返回false
    找是否存在:用二维dp[i][j](到i值时总和为j的子集是否存在)
java 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        int sum=0;
        int max=0;
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
            max=Math.max(max,nums[i]);
        }
        int target=sum/2;
        if(sum%2==1||max>target) return false;
        boolean[] dp=new boolean[target+1];
        dp[0]=true;
        for(int i=0;i<nums.length;i++){
            for(int j=target;j>=1;j--){
                if(j>=nums[i]){
                    dp[j]|=dp[j-nums[i]];
                }
            }
        }
        return dp[target];
    }
}
  1. 最长有效括号
    方法一:动态规划
    对于dp思路,就两种情况对于')'
    1、前一个是(,我只能跟你匹配,但是最长是2+dp[i-2](i>=2)
    2、前一个不是(,最长是2+dp[i-1]+dp[i-dp[i-1]-2],并且i-dp[i-1]是(

我的疑问:

为什么不存在dp[i-1]中某个括号和我匹配

因为其中的括号一一对应,没有能跟你组成有效括号的

dp列举的长度,计算时如果是用dp直接算,用s.charAt是索引,还要-1

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        int cnt=0,n=s.length();
        int[] dp=new int[n+1];
        for(int i=2;i<=n;i++){
            if(s.charAt(i-1)=='(') continue;
            if(s.charAt(i-2)=='(') dp[i]=2+dp[i-2];
            else{
                if(i-dp[i-1]-2>=0&&s.charAt(i-dp[i-1]-2)=='(') dp[i]=2+dp[i-1]+dp[i-dp[i-1]-2];
            }
            cnt=Math.max(cnt,dp[i]);
        }
        return cnt;
    }
}

考试优先两遍扫描法

java 复制代码
class Solution {
    public int longestValidParentheses(String s) {
        int n=s.length(),cnt=0;
        int left=0,right=0;
        for(int i=0;i<n;i++){
            if(s.charAt(i)=='(') left++;
            else right++;
            if(right==left) cnt=Math.max(cnt,right+left);
            if(right>left){
                right=0;
                left=0;
            }
        }
        right=0;
        left=0;
        for(int i=n-1;i>=0;i--){
            if(s.charAt(i)=='(') left++;
            else right++;
            if(right==left) cnt=Math.max(cnt,right+left);
            if(right<left){
                right=0;
                left=0;
            }
        }
        return cnt;
    }
}
相关推荐
皙然2 小时前
线上问题定位与排查实战:从日志到优化的完整思路
java·jvm
炽烈小老头2 小时前
【每天学习一点算法 2026/03/20】单词搜索
学习·算法
无巧不成书02182 小时前
Java核心技术全景解析:从白皮书到实战踩坑
java·开发语言
Roy_Sashulin2 小时前
基于AI的Java编程平台
java·开发语言·人工智能·sashulin·deepseek
旖-旎2 小时前
二分查找(山脉数组的峰顶索引)(5)
c++·算法·leetcode·二分查找·力扣·双指针
大傻^2 小时前
Spring AI Alibaba 企业级实战:从0到1构建智能客服系统
java·人工智能·后端·spring·springaialibaba
阿贵---2 小时前
单元测试在C++项目中的实践
开发语言·c++·算法
进击的小头2 小时前
第14篇:MPC控制案例——无人机高度控制
python·算法·无人机
贼爱学习的小黄2 小时前
NC BIP增加按钮
java