• 竞赛190


     

    定长子串中元音的最大数目

    给你字符串 s 和整数 k 。

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

    英文中的 元音字母 为(aeiou)。

    示例 1:

    输入:s = "abciiidef", k = 3
    输出:3
    解释:子字符串 "iii" 包含 3 个元音字母。
    

    示例 2:

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

    示例 3:

    输入:s = "leetcode", k = 3
    输出:2
    解释:"lee"、"eet" 和 "ode" 都包含 2 个元音字母。
    

    示例 4:

    输入:s = "rhythms", k = 4
    输出:0
    解释:字符串 s 中不含任何元音字母。
    

    示例 5:

    输入:s = "tryhard", k = 4
    输出:1
    

    提示:

    • 1 <= s.length <= 10^5
    • s 由小写英文字母组成
    • 1 <= k <= s.length
    // 超时,即使是避免掉重复 y.includes(s[i]), 特殊情况还是超时,明显就是时间复杂度过高问题,但有不知怎么减少
    /**
     * @param {string} s
     * @param {number} k
     * @return {number}
     */
    var maxVowels = function(s, k) {
        let i=0, len = s.length;
        // let arr = s.split('')
        let y = ['a', 'e', 'i', 'o', 'u'];
        let res = 0;
        let arr = new Array(len).fill(0);
        for(let i=0; i<len; i++){
            if(y.includes(s[i])){
                arr[i] = 1
                // count++
            }
        }
        while(i<len-2){
            let count = 0;
            arr.slice(i, i+k).forEach(f=>{
                if(f===1){
                    count++
                }
            })
            res = Math.max(res, count)
             if(res===k){
                    return k
            }
            i++;
        }
        
    //     while(i<len-2){
    //         let count = 0;
    //         if(y.includes(s[i])){
    //             s.slice(i, i+k).split('').forEach(f=>{
    //                 if(y.includes(f)){
    //                     count++
    //                 }
    //             })
    //             res = Math.max(res, count)
    //             if(res===k){
    //                 return k
    //             }
    //             // i++;
    //         }
    //         i++;
            
    //     }
        return res;
    };
    

      

     

      

    思路: 很多地方会用数组做一个前面一个和后面一个的关系式子,就像dp那样 
    记录某个到某个索引处共出现的次数
    // 就是之前数组不仅要记录是否是”原因字母“,好要记录,到某个索引处之前共有几个”原因字母“,其实当时也想某个”原因字母“必须知道它前后是不是,是有影响的,我当时会想到有没有最大连续的。
    //但是呢,高手用数组记录出现”元音字母“出现的次数。
    // 第二个循环,arr[i]=n1, 之后k个每个加1,最大也就是n1+k,所以最大差值也就是k

    while(i<=len-k){
    res = Math.max(res, arr[i+k]-arr[i]);
    i++;
    }


    /** * @param {string} s * @param {number} k * @return {number} */ var maxVowels = function(s, k) { let t = ['a','e','i','o','u']; let len = s.length; let arr = new Array(len+1).fill(0); for(let i=1; i<=len; i++){ arr[i] = arr[i-1]+(~t.indexOf(s[i-1])?1:0); } console.log(arr) let res = 0; for(let i = k; i <= len; ++ i){ res = Math.max(res, arr[i]-arr[i-k]); } return res };

      

    // 思路:遍历整个字符串的时候,不用截取子字符串,再操作。
    // 先计算出第一个子字符串的需要信息,然后遍历,尾部多一个就+1,头部多一个,不操作,双索引操作。
    /**
     * @param {string} s
     * @param {number} k
     * @return {number}
     */
    var maxVowels = function(s, k) {
        let len = s.length;
        let l = 0, r = k-1;
        let tmp = 0, ans = 0;
        let t = ['a','e','i','o','u'];
        for(let i=l; i<=r; i++){
            if(t.includes(s[i])){
               tmp++
             }
        }
        ans =Math.max(ans, tmp);
        // 必须循环到len-1,因为是从k-1开始的
        while(r!=len-1){
            r++
            if(t.includes(s[r])){
                tmp++
            }
            if(t.includes(s[l])){
                tmp--
            }
            l++;
            ans = Math.max(ans, tmp);
            if(ans === k) return k
        }
        return ans
    };
    

      

    给你一棵二叉树,每个节点的值为 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] 。

    示例 2:

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

    示例 3:

    输入:root = [9]
    输出:1
    

    提示:

    • 给定二叉树的节点数目在 1 到 10^5 之间。
    • 节点值在 1 到 9 之间。
    // 到达底部,拿到这条路径上的所有节点,然后判断是否是回文,但是这个路径总是深度优先遍历的顺序,所有路径都一样,然后就不知怎么写了
    var pseudoPalindromicPaths  = function(root) {
    //     let all = [];
    //     const dfs=(node, arr)=>{
    //         if(!node){
    //             return;
    //         }
    //         arr.push(node.val);
    //         // if(!node.left && !node.right){
    //         //    all.push(arr);
    //         //     return
    //         // }
    //         if(node.left) {
    //             dfs(node.left, arr)
    //         }
            
    //         if(node.right) {
    //             dfs(node.right, arr)
    //         }
            
    //     }
     }
    

      

     var pseudoPalindromicPaths  = function(root) {
        const check=(cnt)=> {
            let odd = 0;
            for(let i = 0; i <= 9; i++) {
                if(cnt[i]&1) {
                    odd++;
                }
            }
            if(odd <= 1) {
                return 1;
            }
            return 0;
        }
        const dfs=(root, cnt)=> {
            if(!root) {
                return 0;
            }
            cnt[root.val] ++;
            if(!root.left && !root.right) {
        // 奇数个数<=1才是伪回文
                let anw = check(cnt);
    // 回溯减去当前值
                cnt[root.val]--;
                console.log('anw: ',anw)
                return anw;
            }
            let anw = 0;
            if(root.left) {
                anw += dfs(root.left, cnt);
            }
            if(root.right) {
                anw += dfs(root.right, cnt);
            }
    // 回溯减去当前值
            cnt[root.val] --;
            console.log('return anw: ',anw)
            return anw;
        }
        let cnt = new Array(10).fill(0);
        return dfs(root, cnt);
     }
    

      

    class Solution {
        int ans=0;
        public int pseudoPalindromicPaths (TreeNode root) {
            if(root==null) return 0;
            helper(root,0);
            return ans;
        }
        
        void helper(TreeNode node,int temp){
            temp^=(1<<node.val);//node节点的val为几就左移几位
            if(node.left==null&&node.right==null){//判断是否叶子节点
                if(temp==0||(temp&(temp-1))==0){//判断是否为伪回文
                    ans++;
                }
            }
            if(node.left!=null) helper(node.left,temp);
            if(node.right!=null) helper(node.right,temp);
            return;
        }
    }
    
    
    

      

    作者:rational-irrationality
    链接:https://leetcode-cn.com/problems/pseudo-palindromic-paths-in-a-binary-tree/solution/java-dfs-shuang-bai-by-rational-irrationality/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    shell-条件测试
    51Nod 1279 扔盘子 (思维+模拟)
    51Nod 1042 数字0-9的数量(数位DP)
    Codeforces 1138B Circus (构造方程+暴力)
    51nod 1133 不重叠的线段 (贪心,序列上的区间问题)
    51nod 1091 线段的重叠(贪心)
    EOJ Monthly 2019.2 E 中位数 (二分+中位数+dag上dp)
    牛客练习赛39 C 流星雨 (概率dp)
    牛客练习赛39 B 选点(dfs序+LIS)
    Educational Codeforces Round 57
  • 原文地址:https://www.cnblogs.com/zhangzs000/p/12950678.html
Copyright © 2020-2023  润新知