LeetCode 热题 HOT 100 -------32. 最长有效括号 (动态规划、栈、双指针) 309. 最佳买卖股票时机含冷冻期(动态规划)

dsadd在这里插入图片描述

//动态规划: 边界,以及转移方程
class Solution {
    public int longestValidParentheses(String s) {
        int[] dp = new int[s.length()];
        int maxCount = 0;
        for(int i=1 ; i < s.length() ; i++){
            //只有当为')'我们才能继续查找
            if(s.charAt(i)==')'){
                if(s.charAt(i-1) == '('){
                    dp[i] = (i-2 >= 0 ? dp[i-2] : 0) +2;
                }else if(i-dp[i-1]>0 && s.charAt(i-dp[i-1]-1) =='('){//这时候也就是s.charAt(i-1)==')',这时候就要看i-dp[charAt(i-1)]-1了
                    dp[i] = dp[i-1] + (i-dp[i-1]-2>=0 ? dp[i-dp[i-1]-2] : 0) +2;
                }
                maxCount = Math.max(maxCount , dp[i]);
            }
        }
        return maxCount;
    }
}

//双指针
class Solution {
    public int longestValidParentheses(String s) {
        //"leftCount"代表的是“(”,"rightCount"代表的是")"
        int leftCount =0 , rightCount = 0;
        int maxCount=0;
        for(int i=0 ; i<s.length() ; i++){
            if(s.charAt(i) == '('){
                leftCount++;
            }else{
                rightCount++;
            }
            //当")"多了,就要重新计数了
            if(leftCount == rightCount){
                maxCount = Math.max(maxCount,2*leftCount);
            }else if(rightCount>leftCount){
                leftCount = 0 ; 
                rightCount =0;
            }
        }
        leftCount = rightCount = 0;
        //但是上面那种少了一种情况,就是'('一直比')'多
        //因此反向遍历即可
        for(int i = s.length()-1 ; i>=0 ; i--){
            if(s.charAt(i)=='('){
                leftCount++;
            }else{
                rightCount++;
            }
            if(leftCount == rightCount){
                maxCount = Math.max(maxCount , 2*leftCount);
            }else if(leftCount > rightCount){
                leftCount = 0;
                rightCount = 0;
            }
        }
        return maxCount;
    }
}
// //通过栈计算,具体做法是我们始终保持栈底元素为当前已经遍历过的元素中「最后一个没有被匹配的右括号的下标
class Solution {
    public int longestValidParentheses(String s) {
        //通过栈存储下标,我们栈中最底层存储的都是不能匹配的")"
        Deque<Integer> stack = new LinkedList<>();
        stack.push(-1);             //是为了保证最后一个没有被匹配的右括号的下标
        int maxCount = 0;
        for(int i=0 ; i<s.length() ; i++){
            if(s.charAt(i) == '('){
                stack.push(i);     
            }else{
                stack.pop();   //因为我们栈顶放的是"「最后一个没有被匹配的右括号的下标"所以要先弹出"
                //当为空时  
                if(stack.isEmpty()){
                    stack.push(i);
                }else{
                    maxCount = Math.max(maxCount , i - stack.peek());
                }
            }
        }
        return maxCount;
    }
}

dsddds在这里插入图片描述

/**思路巧妙,动态规划
    因为需要买之前需要卖出也就相当于没有了股票,还有可能就是本来就不持股,还有一种是持股,因此我们要通过二维数组进行遍历
    dp[i][0]、dp[0][1]、dp[0][2]
    动态规划,我们找边界条件以及写转移方程(根据有无股票进行分类)
    1、持股:dp[i][0]: Math.max(dp[i-1][0],dp[i-1][1] - prices[i])
    2、不持股(因为本来也不持股)dp[i][1]: Math.max(dp[i-1,1],dp[i-1,2])
    3、不持股但是在冷冻期(是因为卖了):dp[i][2]: dp[i-1][0] + prices[i]
    然后找边界:
    dp[0][0]=0  dp[0][1]=-prices[0] dp[0][2] = 0
*/
class Solution {
    public int maxProfit(int[] prices) {
        int len = prices.length;
        if(len == 0){
           return 0;
        }
        int[][] dp = new int[len][3];
        //边界
        dp[0][0] = -prices[0];
        dp[0][1] = 0;
        dp[0][2] = 0;

        //转移方程
        for(int i=1; i<len ; i++){
            dp[i][0] = Math.max(dp[i-1][0],dp[i-1][1] - prices[i]);
            dp[i][1] = Math.max(dp[i-1][1],dp[i-1][2]);
            dp[i][2] = dp[i-1][0] + prices[i];
        }
        return Math.max(dp[len-1][1],dp[len-1][2]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值