• 177 竞赛


    验证二叉树

    二叉树上有 n 个节点,按从 0 到 n - 1 编号,其中节点 i 的两个子节点分别是 leftChild[i] 和 rightChild[i]

    只有 所有 节点能够形成且 只 形成 一颗 有效的二叉树时,返回 true;否则返回 false

    如果节点 i 没有左子节点,那么 leftChild[i] 就等于 -1。右子节点也符合该规则。

    注意:节点没有值,本问题中仅仅使用节点编号。

    示例 1:

    输入:n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
    输出:true
    

    示例 2:

    输入:n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
    输出:false
    

    示例 3:

    输入:n = 2, leftChild = [1,0], rightChild = [-1,-1]
    输出:false
    

    示例 4:

    输入:n = 6, leftChild = [1,-1,-1,4,-1,-1], rightChild = [2,-1,-1,5,-1,-1]
    输出:false
    

    提示:

    • 1 <= n <= 10^4
    • leftChild.length == rightChild.length == n
    • -1 <= leftChild[i], rightChild[i] <= n - 1
    /**
     * @param {number} n
     * @param {number[]} leftChild
     * @param {number[]} rightChild
     * @return {boolean}
     */
    var validateBinaryTreeNodes = function(n, leftChild, rightChild) {
        let fa = new Array(n).fill(-1);
            // 如果一个节点有两个fa就是问题。或者循环的fa,或者是没有root。
            for(let i = 0;i<n;i++) {
                if(leftChild[i] != -1) {
                    if(fa[leftChild[i]] != -1) return false;
                    fa[leftChild[i]] = i;
                }
                if(rightChild[i] != -1) {
                    if(fa[rightChild[i]] != -1) return false;
                    fa[rightChild[i]] = i;
                }
            }
    
            let count = 0;
            for(let i = 0;i<n;i++) {
                if(fa[i] == -1) count++;
            }
            return count == 1;
    }
    /*
    var validateBinaryTreeNodes = function(n, l, r) {
        let vis = new Array(n).fill(0);
        let flag = 0;
            for(let i=0;i<n;i++)
            {
                if(l[i]!=-1)vis[l[i]]++;
                if(r[i]!=-1)vis[r[i]]++;
            }
            
            for(let i=0;i<n;i++)
            {
                if(vis[i]==0)
                {
                    if(!flag)flag=1;
                    else return 0;
                }
                if(vis[i]>1)return 0;
            }
            if(!flag)return 0;
           
            return 1;
    }
    */
    /*
    var validateBinaryTreeNodes = function(n, leftChild, rightChild) {
            let id = new Array(n).fill(0);
            
            for (let i = 0; i < n; ++i) {
                if (leftChild[i] != -1)
                    id[leftChild[i]]++;
                if (rightChild[i] != -1) 
                    id[rightChild[i]]++;
            }
            
            let count = 0;
            for (let i = 0; i < n; ++i) {
                if (id[i] == 2) return false;
                if (id[i] == 0) ++count;
                
            }
            
            return count == 1;
    }
    */
    /*
    var validateBinaryTreeNodes = function(n, leftChild, rightChild) {
        const parent = new Array(n).fill(-1);
        for (let i = 0; i < n; i++) {
            if (leftChild[i] > -1) {
                if (parent[leftChild[i]] > -1) return false;
                parent[leftChild[i]] = i;
            }
            if (rightChild[i] > -1) {
                if (parent[rightChild[i]] > -1) return false;
                parent[rightChild[i]] = i;
            }
        }
        let root = -1;
        for (let i = 0; i < n; i++) {
            if (parent[i] === -1) {
                if (root > -1) return false;
                root = i;
            }
        }
        let num = 0;
        var dfs = function(i) {
            num++;
            if (leftChild[i] > -1) dfs(leftChild[i]);
            if (rightChild[i] > -1) dfs(rightChild[i]);
        }
        dfs(root);
        return num === n;
    };
    */
    /*
    var validateBinaryTreeNodes = function(n, leftChild, rightChild) {
        for(let i=0; i<n; i++){
           let l =  leftChild[i],
               r = rightChild[i];
            let sub = [];
            if( l!==-1){
               sub.push(l)
               }
            if(l!==-1) {
                sub.push(l)
            }
            let arr = [];
            while(sub.length){
                let node = sub.shift();
                
            }
        }
    };
    */
    

      

    var validateBinaryTreeNodes = function(n, leftChild, rightChild) {
        const queue = [0];
        const set = new Set(queue);
    
        while (queue.length) {
            const i = queue.shift();
            
            if (set.has(leftChild[i])) {
                return false;
            } else if (leftChild[i] !== -1) {
                set.add(leftChild[i]);
                queue.push(leftChild[i]);
            }
    
            if (set.has(rightChild[i])) {
                return false;
            } else if (rightChild[i] !== -1) {
                set.add(rightChild[i]);
                queue.push(rightChild[i]);
            }
        }
    
        return set.size === n;
    };
    
    // 如果存在环,就不是二叉树,set中元素个数不为n就存在断层,其实还有一种可能就是根结点不是0;
    当时就是不知道怎么判断存在环,和断层。while(queue.length){}有这个趋势,但是对数组中节点和索引反应不过来。
    先 0 这个节点,拿出它的左节点1和右节点2,放到queue中。在弹出1这个节点,它又是索引拿到它的左3和右节点4,如果3或4存在于set中就存在。1->0(3或4)就是环

      

    形成三的最大倍数

    给你一个整数数组 digits,你可以通过按任意顺序连接其中某些数字来形成 3 的倍数,请你返回所能得到的最大的 3 的倍数。

    由于答案可能不在整数数据类型范围内,请以字符串形式返回答案。

    如果无法得到答案,请返回一个空字符串。

    示例 1:

    输入:digits = [8,1,9]
    输出:"981"
    

    示例 2:

    输入:digits = [8,6,7,1,0]
    输出:"8760"
    

    示例 3:

    输入:digits = [1]
    输出:""
    

    示例 4:

    输入:digits = [0,0,0,0,0,0]
    输出:"0"
    

    提示:

    • 1 <= digits.length <= 10^4
    • 0 <= digits[i] <= 9
    • 返回的结果不应包含不必要的前导零。
    /**
     * @param {number[]} digits
     * @return {string}
     */
    var largestMultipleOfThree = function(digits) {
        digits.sort((a, b) => a - b);
        const map = [[], [], []];
        
        let sum = 0;
        for (const n of digits) {
            map[n % 3].push(n);
            sum += n;
        }
    
        function format(arr) {
            arr.sort((a, b) => b - a);
            while (arr.length > 1 && arr[0] === 0) {
                arr.shift();
            }
            return arr.join('');
        }
    
        // console.log(sum, sum % 3);
    
        if (sum % 3 === 0) {
            return format(digits);
        } else if (sum % 3 === 1) {
            if (map[1].length >= 1) {
                map[1].shift();
                return format([...map[0], ...map[1], ...map[2]]);
            } else if (map[2].length >= 2) {
                map[2].shift();
                map[2].shift();
                return format([...map[0], ...map[1], ...map[2]]);
            } else {
                return '';
            }
        } else {
            if (map[2].length >= 1) {
                map[2].shift();
                return format([...map[0], ...map[1], ...map[2]]);
            } else if (map[1].length >= 2) {
                map[1].shift();
                map[1].shift();
                return format([...map[0], ...map[1], ...map[2]]);
            } else {
                return '';
            }
        }
    };
    /*
    var largestMultipleOfThree = function(digits) {
         const num = new Array(10).fill(0);
        let sum = 0;
        for (let i = 0; i < digits.length; i++) {
            sum += digits[i];
            num[digits[i]]++;
        }
        if (sum % 3 === 1) {
            for (let i = 1; i < 9; i+=3) {
                if (num[i] > 0) {
                    num[i]--;
                    sum-= i;
                    break;
                }
            }
            if (sum % 3 === 1) {
                for (let i = 2; i < 9; i+=3) {
                    if (num[i] > 0) {
                        num[i]--;
                        sum-= i;
                        if (sum % 3 === 0) break;
                    }
                    if (num[i] > 0) {
                        num[i]--;
                        sum-= i;
                        if (sum % 3 === 0) break;
                    }
                }
            }
        }
        if (sum % 3 === 2) {
            for (let i = 2; i < 9; i+=3) {
                if (num[i] > 0) {
                    num[i]--;
                    sum-= i;
                    break;
                }
            }
            if (sum % 3 === 2) {
                for (let i = 1; i < 9; i+=3) {
                    if (num[i] > 0) {
                        num[i]--;
                        sum-= i;
                        if (sum % 3 === 0) break;
                    }
                    if (num[i] > 0) {
                        num[i]--;
                        sum-= i;
                        if (sum % 3 === 0) break;
                    }
                }
            }
        }
        if (!sum) return num[0] ? '0' : '';
        let result = '';
        for (let i = 9; i > -1; i--) {
            for (let j = 0; j < num[i]; j++) {
                result = result + i;
            }
        }
        return result;
    }
    */
    /*
    以前的想法: 
    排序,去掉最小的,一直去掉最小的,后果就是有时去掉的不是最小的也能满足条件,这样它的位数会很长,自然数字就是最大的。
    后来想:
    DP, len(digits) = Math.max(len(digits), len)
    var largestMultipleOfThree = function(digits) {
        digits.sort((a,b)=>a-b);
        let len = digits.length;
        let n = len;
        let sub = [];
        let s = 0;
        let index0=0;
        while(n--){
           let sum = digits.reduce((a,b)=>a+b);
             
            if(sum === 0){
                return "0"
            }else if(sum%3===0){
                
                let ii = digits.indexOf(s);
                if(ii>-1 && s!==0){
                   digits.splice(ii, 1);
                    digits.splice(index0, 0, ...sub)
                }
                
                break;
            }else{
                let j = 0;
                len = digits.length;
                while(digits.length ===len){
                      if(digits[j]!==0){
                          index0 = j;
                          s+=digits[j];
                          sub.push(digits[j])
                        digits.splice(j, 1);
                    } else {
                        j++;
                    } 
                }
            }
        }
        return digits.reverse().join('')
    };
    */
    var largestMultipleOfThree = function(digits) {
        let arr = new Array(10).fill(0), sum = 0;
        let ans = '';
        const del=(m)=>{
            for(let i=m;i<=9;i+=3)if(arr[i]){arr[i]--,sum-=i;return 1;}
            return 0;
        }
        digits.forEach(f=>{
            arr[f]++;
            sum+=f
        })
        if(sum%3 ===1){
            if(!del(1)){
                del(2);
                del(2);
            }
        }
        if(sum%3 ===2){
            if(!del(2)){
                del(1);
                del(1);
            }
        }
        if(!sum && arr[0]){
            return "0";
        }
        for(let i=9;i>=0;i--)while(arr[i]--)ans+=i+'';
            return ans;
    }
    以前的想法: 
    排序,去掉最小的,一直去掉最小的,后果就是有时去掉的不是最小的也能满足条件,这样它的位数会很长,自然数字就是最大的。
    后来想:
    DP, len(digits) = Math.max(len(digits), len),还是不对。
    这个数是0~9这10个数构成,完全可以用数组统计每个数对应的个数,然后从后向前遍历拼接最大数

  • 相关阅读:
    oracle lengthb
    layui-rp
    1709052基于框架新建 子项目
    echar 常用单词
    Leetcode 481.神奇字符串
    Leetcode 480.滑动窗口中位数
    Leetcode 479.最大回文数乘积
    Leetcode 477.汉明距离总和
    Leetcode 476.数字的补数
    Leetcode 475.供暖气
  • 原文地址:https://www.cnblogs.com/zhangzs000/p/12349213.html
Copyright © 2020-2023  润新知