leetcode第190场周赛(2020/05/24)

好几周没打周赛了,今天打了一次,第一次ak,感动。下面是本次周赛。

第一题、检查单词是否为句中其他单词的前缀

难度:easy,链接:5416. 检查单词是否为句中其他单词的前缀

给你一个字符串 sentence 作为句子并指定检索词为 searchWord ,其中句子由若干用 单个空格 分隔的单词组成。

请你检查检索词 searchWord 是否为句子 sentence 中任意单词的前缀。

    如果 searchWord 是某一个单词的前缀,则返回句子 sentence 中该单词所对应的下标(下标从 1 开始)。
    如果 searchWord 是多个单词的前缀,则返回匹配的第一个单词的下标(最小下标)。
    如果 searchWord 不是任何单词的前缀,则返回 -1 。

字符串 S 的 「前缀」是 S 的任何前导连续子字符串。

输入:sentence = "i love eating burger", searchWord = "burg"
输出:4
解释:"burg" 是 "burger" 的前缀,而 "burger" 是句子中第 4 个单词。

题解:先把句子split,然后从头开始判断是否是前缀,是就break然后返回当前单词下标即可。

代码:

class Solution {
    public int isPrefixOfWord(String sentence, String searchWord) {
        String[] words = sentence.split(" ");
        int len = searchWord.length();
        for (int i = 0; i < words.length; i++){
            if (words[i].length() >=len && words[i].substring(0,len).equals(searchWord)){
                return i + 1;
            }
        }
        return -1;
    }
}

第二题:定长子串中元音的最大数目

难度:中等, 链接:5417. 定长子串中元音的最大数目

题目:

给你字符串 s 和整数 k 。

请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。

英文中的 元音字母 为(a, e, i, o, u)。

输入:s = "abciiidef", k = 3
输出:3
解释:子字符串 "iii" 包含 3 个元音字母。
输入:s = "aeiou", k = 2
输出:2
解释:任意长度为 2 的子字符串都包含 2 个元音字母

题解:滑动窗口题,窗口大小为k,每次滑动计算元音字母数

代码:

class Solution {
    public boolean isvalid(char c)//判断字母是否是元音字母
    {
        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c== 'u'){
            return true;
        }else{
            return false;
        }
    }
    public int maxVowels(String s, int k) {
        int len = s.length();
        int res = 0;
        int num = 0;
        for (int i = 0 ; i < k; i++)//窗口初始元音字母数
        {
            if (isvalid(s.charAt(i))){
                num++;
            }
        }
        res = num;
        for (int i = k; i < len ; i++)//窗口滑动
        {
            if (isvalid(s.charAt(i))){
                num++;
            } 
            if (isvalid(s.charAt(i - k))){
                num--;
            }
            res = Math.max(res,num);
        }
        return res;
    }
}

第三题、 二叉树中的伪回文路径

难度:medium   链接:5418. 二叉树中的伪回文路径

题目:

给你一棵二叉树,每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的,当它满足:路径经过的所有节点值的排列中,存在一个回文序列。

请你返回从根到叶子节点的所有路径中 伪回文 路径的数目。

示例 1:

输入:root = [2,3,1,3,1,null,1]
输出:2
解释:上图为给定的二叉树。总共有 3 条从根到叶子的路径:红色路径 [2,3,3] ,绿色路径 [2,1,1] 和路径 [2,3,1] 。
     在这些路径中,只有红色和绿色的路径是伪回文路径,因为红色路径 [2,3,3] 存在回文排列 [3,2,3] ,绿色路径 [2,1,1] 存在回文排列 [1,2,1] 。

将题目分解:找到所有的根到叶子的路径和判断路径是否是回文路径两个问题。第一个问题可以dfs解决,第二个问题因为一个回文路径只能有一个或0个奇数的数字个数,比如101只有1个奇数数字个数(1个0),11只有0个奇数数字个数(0个0),12因为有2个奇数数字个数(1个1,1个2),怎么排列都不是回文数,所以不是伪回文路径。所以这道题解法就出来了,dfs求出所有路径,然后用map存储数字个数判断(因为只有9个数字,所以判断也不慢)。这种是暴力解法,也可以dfs的时候就判断,可以快一点

代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    int res = 0;
    HashMap<Integer,Integer> map = new HashMap();
    public int pseudoPalindromicPaths (TreeNode root) {
        map.put(root.val,map.getOrDefault(root.val,0) + 1);
        dfs(root);
        return res;
    }
    void dfs(TreeNode root)
    {
        if (root.left == null && root.right == null){
            if (isvalid(map))res++;
            return;
        } 
        if (root.left != null)
        {
            map.put(root.left.val,map.getOrDefault(root.left.val,0) + 1);
            dfs(root.left);
            map.put(root.left.val,map.get(root.left.val) - 1);
        }
        if (root.right != null)
        {
            map.put(root.right.val,map.getOrDefault(root.right.val,0) + 1);
            dfs(root.right);
            map.put(root.right.val,map.get(root.right.val) - 1);
        }
    
        
    }
    boolean isvalid(HashMap<Integer,Integer> map){
        int odds = 0;
        for (Integer i:map.values())
        {
            if (i % 2 == 1) odds++; 
        }
        if (odds <= 1) return true;
        else return false;
    }
}

第四题、 两个子序列的最大点积

难度:困难 链接:5419. 两个子序列的最大点积

题目:

给你两个数组 nums1 和 nums2 。

请你返回 nums1 和 nums2 中两个长度相同的 非空 子序列的最大点积。

数组的非空子序列是通过删除原数组中某些元素(可能一个也不删除)后剩余数字组成的序列,但不能改变数字间相对顺序。比方说,[2,3,5] 是 [1,2,3,4,5] 的一个子序列而 [1,5,3] 不是。

输入:nums1 = [2,1,-2,5], nums2 = [3,0,-6]
输出:18
解释:从 nums1 中得到子序列 [2,-2] ,从 nums2 中得到子序列 [3,-6] 。
它们的点积为 (2*3 + (-2)*(-6)) = 18 。

题解:这道题如果能联想到最长公共子序列那题的话,就迎刃而解了,一个模板。

dp[i][j] = max(dp[i-1][j],dp[i][j-1],max(0,dp[i-1][j-1] + nums1[i]) * nums2[j]);//dp[i][j]为nums1的前i个数字形成的子数组和nums2的前j个数字形成的子数组的长度相同的非空子序列的最大点积。

代码:

class Solution {
    public int maxDotProduct(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int len2 = nums2.length;
        int[][] dp = new int[len1][len2];//dp[i][j]为nums1的前i个数字形成的子数组和nums2的前j个数字形成的子数组的长度相同的非空子序列的最大点积。
        dp[0][0] = nums1[0] * nums2[0];
        for (int i = 1; i < len1;i++)
        {
            dp[i][0] = Math.max(dp[i-1][0] , nums1[i] * nums2[0]);
        }
        for (int i = 1; i < len2;i++)
        {
            dp[0][i] = Math.max(dp[0][i - 1] , nums1[0] * nums2[i]);
        }
        for (int i = 1; i < len1; i++)
        {
            for (int  j = 1; j < len2; j++)
            {
                dp[i][j] = Math.max(dp[i - 1][j] , Math.max(dp[i][j - 1], Math.max(0,dp[i - 1][j - 1]) + nums1[i] * nums2[j]));//max里的max因为非空,所以dp[i-1][j-1]如果为0,可以抛弃
            }
        }
        return dp[len1 - 1][len2 - 1];
        
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值