• [Leetcode Weekly Contest]260


    链接:LeetCode

    [Leetcode]2016. 增量元素之间的最大差值

    给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。

    返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。

    遍历即可。

    class Solution {
        public int maximumDifference(int[] nums) {
            int res = -1;
            int n = nums.length;
            for(int i =0;i<n;++i) {
                for(int j=i+1;j<n;++j) {
                    if(nums[j] > nums[i]) {
                        res = Math.max(res,nums[j]-nums[i]);
                    }
                }
            }
            return res;
        }
    }
    

    [Leetcode]2017. 网格游戏

    给你一个下标从 0 开始的二维数组 grid ,数组大小为 2 x n ,其中 grid[r][c] 表示矩阵中 (r, c) 位置上的点数。现在有两个机器人正在矩阵上参与一场游戏。

    两个机器人初始位置都是 (0, 0) ,目标位置是 (1, n-1) 。每个机器人只会 向右 ((r, c) 到 (r, c + 1)) 或 向下 ((r, c) 到 (r + 1, c)) 。

    游戏开始,第一个 机器人从 (0, 0) 移动到 (1, n-1) ,并收集路径上单元格的全部点数。对于路径上所有单元格 (r, c) ,途经后 grid[r][c] 会重置为 0 。然后,第二个 机器人从 (0, 0) 移动到 (1, n-1) ,同样收集路径上单元的全部点数。注意,它们的路径可能会存在相交的部分。

    第一个 机器人想要打击竞争对手,使 第二个 机器人收集到的点数 最小化 。与此相对,第二个 机器人想要 最大化 自己收集到的点数。两个机器人都发挥出自己的 最佳水平 的前提下,返回 第二个 机器人收集到的 点数 。

    由于机器人只会向下和向右行走,可以遍历每一种情况,计算最优解。另外,在比较第二个机器人不同路线的点数时,可以利用前缀和来优化算法复杂度。

    class Solution {
        public long gridGame(int[][] grid) {
            long sum1 = 0, sum2 = Arrays.stream(grid[0]).asLongStream().sum(); // 大数溢出
            int n = grid[0].length;
            long res = Long.MAX_VALUE;
            for(int i=0; i<n; ++i) {
                sum2 -= grid[0][i];
                if(i!=0) sum1 += grid[1][i-1];
                long cur = Math.max(sum1, sum2);
                res = Math.min(res, cur);
            }
            return res;
        }
    }
    

    [Leetcode]2018. 判断单词是否能放入填字游戏内

    给你一个 m x n 的矩阵 board ,它代表一个填字游戏 当前 的状态。填字游戏格子中包含小写英文字母(已填入的单词),表示 空 格的 ' ' 和表示 障碍 格子的 '#' 。

    如果满足以下条件,那么我们可以 水平 (从左到右 或者 从右到左)或 竖直 (从上到下 或者 从下到上)填入一个单词:

    • 该单词不占据任何 '#' 对应的格子。
    • 每个字母对应的格子要么是 ' ' (空格)要么与 board 中已有字母 匹配 。
    • 如果单词是 水平 放置的,那么该单词左边和右边 相邻 格子不能为 ' ' 或小写英文字母。
    • 如果单词是 竖直 放置的,那么该单词上边和下边 相邻 格子不能为 ' ' 或小写英文字母。

    给你一个字符串 word ,如果 word 可以被放入 board 中,请你返回 true ,否则请返回 false 。

    深度优先遍历。对每一个方格向上,下,左,右遍历判断即可。

    class Solution {
        enum Direction
        {
            TOP,DOWN,LEFT,RIGHT;
        }
        public boolean placeWordInCrossword(char[][] board, String word) {
            int n = board.length, m=board[0].length;
            int lenWord = word.length();
            for(int i=0;i<n;++i) {
                for (int j=0; j<m; ++j) {
                    if(board[i][j]=='#') continue;
                    if((i==0 || board[i-1][j]=='#') && i<=n-lenWord && dfs(board,word,i,j,Direction.DOWN)) return true;
                    if((i==n-1 || board[i+1][j]=='#') && i>=lenWord-1 && dfs(board,word,i,j,Direction.TOP)) return true;
                    if((j==0 || board[i][j-1]=='#') && j<=m-lenWord && dfs(board,word,i,j,Direction.RIGHT)) return true;
                    if((j==m-1 || board[i][j+1]=='#') && j>=lenWord-1 && dfs(board,word,i,j,Direction.LEFT)) return true;
                }
            }
            return false;
        }
    
        public boolean dfs(char[][] board, String word, int i, int j, Direction dir) {
            int n = board.length, m=board[0].length;
            int lenWord = word.length();
            for(int ind=0;ind<lenWord;ind++) {
                if (board[i][j] != ' ' && board[i][j]!=word.charAt(ind)) return false;
                if(dir == Direction.DOWN) i ++;
                if(dir == Direction.TOP) i --;
                if(dir == Direction.RIGHT) j ++;
                if(dir == Direction.LEFT) j --;
            }
            if(i>=0 && i<=n-1 && j>=0 && j<=m-1 && board[i][j]!='#') return false;
            return true;
        }
    }
    

    [Leetcode]2019. 解出数学表达式的学生分数

    给你一个字符串 s ,它 只 包含数字 0-9 ,加法运算符 '+' 和乘法运算符 '' ,这个字符串表示一个 合法 的只含有 个位数数字 的数学表达式(比方说 3+52)。有 n 位小学生将计算这个数学表达式,并遵循如下 运算顺序 :

    • 按照 从左到右 的顺序计算 乘法 ,然后
    • 按照 从左到右 的顺序计算 加法 。

    给你一个长度为 n 的整数数组 answers ,表示每位学生提交的答案。你的任务是给 answer 数组按照如下 规则 打分:

    • 如果一位学生的答案 等于 表达式的正确结果,这位学生将得到 5 分。
    • 否则,如果答案由 一处或多处错误的运算顺序 计算得到,那么这位学生能得到 2 分。
    • 否则,这位学生将得到 0 分。

    请你返回所有学生的分数和。

    逆波兰表达式+区间DP。计算表达式的正确结果可以使用逆波兰表达式。而计算由 一处或多处错误的运算顺序得到的 错误答案,则可以采取分治的方法,即每一步选择第几个运算符为当前运算,将字符串分为左右两边,再对左右两边的字符串递归求解,由于分解过程中存在分解相同的情况,可以用map作为记忆化存储。

    class Solution {
        HashMap<String, Set<Integer>> hash = new HashMap<>();//用于记忆化搜索
        //计算表达式的正确值
        public int result(String s){
            Deque<Integer> q = new LinkedList();
            Deque<Character> cq = new LinkedList();
            int idx = 0;
            for(int i = 0;i < s.length();i ++){
                if(s.charAt(i) >= '0' && s.charAt(i) <= '9'){
                    q.offerFirst(s.charAt(i) - '0');
                    if(!cq.isEmpty() && cq.peekFirst() == '*'){
                        int n1 = q.pollFirst();
                        int n2 = q.pollFirst();
                        q.offerFirst(n1 * n2);
                        cq.pollFirst();
                    }
                }else{
                    cq.offerFirst(s.charAt(i));
                }
            }
            while(!cq.isEmpty()){
                int n1 = q.pollFirst();
                int n2 = q.pollFirst();
                q.offerFirst(n1 + n2);
                cq.pollFirst();
            }
            return q.peekFirst();
        }
    
    
        public int scoreOfStudents(String s, int[] answers) {
            var nums = new ArrayList<Integer>();
            var ops = new ArrayList<Character>();
            int trueAnswer = result(s);
            for(int ind=0; ind<s.length();++ind){
                if((ind&1)!=0) ops.add(s.charAt(ind));
                else nums.add((int)(s.charAt(ind)-'0'));
            }
            var twoAnswer = dfs(nums,ops,0,nums.size()-1);
            int res = 0;
            for (var answer:
                 answers) {
                if(answer == trueAnswer) res += 5;
                else if(twoAnswer.contains(answer)) res += 2;
            }
            return res;
        }
    
        public HashSet<Integer> dfs(List<Integer> nums,List<Character> ops, int i, int j) {
            String key = i+"-"+j;
            if(hash.containsKey(key)) {
                return (HashSet<Integer>)hash.get(key);
            }
            var hashSet = new HashSet<Integer>();
            if(i == j) {
                hashSet.add(nums.get(i));
                hash.put(key,hashSet);
                return hashSet;
                //hash.put(key,new HashSet<Integer>(){{add(nums.get(i));}});
                //return (HashSet<Integer>)hash.get(key);
            }
            for(int ind=i;ind<j;ind++)
            {
                var nums1 = dfs(nums,ops,i,ind);
                var nums2 = dfs(nums,ops,ind+1,j);
                var op = ops.get(ind);
                for (int num1:nums1) {
                    for (int num2:nums2) {
                        if(op=='+' && num1+num2<=1000) hashSet.add(num1+num2);
                        else if(op=='*' && num1*num2<=1000) hashSet.add(num1*num2);
                    }
                }
                hash.put(key,hashSet);
            }
            return hashSet;
        }
    }
    

    Leetcode

  • 相关阅读:
    05 drf源码剖析之认证
    04 drf源码剖析之版本
    03 drf源码剖析之视图
    02 drf源码剖析之快速了解drf
    OA之为用户设置角色和为用户设置权限
    EasyUI之datagrid的使用
    C#之反射
    EasyUI之Layout布局和Tabs页签的使用
    Memcached的使用
    Log4Net的简单使用
  • 原文地址:https://www.cnblogs.com/hellojamest/p/15351021.html
Copyright © 2020-2023  润新知