Leetcode刷题 2021.01.20

Leetcode1218 最长定差子序列

给你一个整数数组 arr 和一个整数 difference,请你找出并返回 arr 中最长等差子序列的长度,该子序列中相邻元素之间的差等于 difference 。

今天leetcode不知道怎么回事,明明做了三道新题,不给加积分。只能又做了一道。
这题还是比较基础的动态规划题的,其实也没有特意用动态规划做,可能题做多了真的有点感觉了。其实动态规划也就是记忆化搜索而已。对于这题,从后往前遍历,用一个map记录最长的等差数列。遍历的时候,找一下map里有没有可能的等差数列就行了。看了下其他做法,用一个大的数组模拟map的,差不多的做法,也算是空间换时间吧。

class Solution {
    public int longestSubsequence(int[] arr, int difference) {
        int n = arr.length;
        //用一个map记录
        Map<Integer, Integer> memo = new HashMap<>();
        int res = 0;
        //从后往前遍历
        for(int i = n - 1; i >= 0; i--){
            int count = 1;
            //如果map里有,说明在这个元素之后存在一个可行的等差数列
            if (memo.containsKey(arr[i] + difference)){
                count += memo.get(arr[i] + difference);
            }
            //把自己加进去,同时记录当前自己最长的长度
            memo.put(arr[i], count);
            //更新全局
            res = Math.max(res, count);
        }

        return res;
    }
}

Leetcode1219 黄金矿工

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。

为了使收益最大化,矿工需要按以下规则来开采黄金:

每当矿工进入一个单元,就会收集该单元格中的所有黄金。
矿工每次可以从当前位置向上下左右四个方向走。
每个单元格只能被开采(进入)一次。
不得开采(进入)黄金数目为 0 的单元格。
矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。

非常正常的DFS回溯题,基本都不需要怎么改,因为矩阵不大,所以也没去优化了。比较基础。

class Solution {
    public int getMaximumGold(int[][] grid) {
        int m = grid.length, n = grid[0].length;
        int res = 0;

        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                res = Math.max(res, helper(grid, i, j));
            }
        }

        return res;

    }

    private int helper(int[][] grid, int i, int j){
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0){
            return 0;
        }
        int temp = grid[i][j];
        grid[i][j] = 0;
        int u = helper(grid, i + 1, j);
        int d = helper(grid, i - 1, j);
        int l = helper(grid, i, j - 1);
        int r = helper(grid, i, j + 1);

        int max = Math.max(Math.max(u, d), Math.max(l, r));
        grid[i][j] = temp;

        return max + grid[i][j];
        
    }
}

Leetcode1190 反转每对括号间的子串

给出一个字符串 s(仅含有小写英文字母和括号)。

请你按照从括号内到外的顺序,逐层反转每对匹配括号中的字符串,并返回最终的结果。

注意,您的结果中 不应 包含任何括号。

对这种递归题有点不熟悉,调试了半天没调出来,还是想复杂了。其他题解有用栈做的,其实都是一回事。递归也就是用了虚拟机栈嘛。
思路就是递归,维护全局的索引,遇到左括号就递归,右括号退出,否则加到StringBuilder里面。

class Solution {
    int index = 0;
    public String reverseParentheses(String s) {
    	//字符串题用StringBuilder节约空间
        StringBuilder sb = new StringBuilder();
        while (index < s.length()){
            char c = s.charAt(index++);
            //左括号递归,注意要翻转
            if (c == '('){
                sb.append((new StringBuilder(reverseParentheses(s))).reverse());
                //右括号退出
            }else if (c == ')'){
                break;
                //否则加到StringBuilder里面
            }else{
                sb.append(c);
            }
        }


        return sb.toString();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值