码迷,mamicode.com
首页 > 其他好文 > 详细

174竞赛

时间:2020-02-05 20:09:00      阅读:76      评论:0      收藏:0      [点我收藏+]

标签:return   math   const   fun   quicksort   log   null   yun   tps   

分裂二叉树的最大乘积

给你一棵二叉树,它的根为 root 。请你删除 1 条边,使二叉树分裂成两棵子树,且它们子树和的乘积尽可能大。

由于答案可能会很大,请你将结果对 10^9 + 7 取模后再返回。

 

示例 1:

技术图片

技术图片

输入:root = [1,2,3,4,5,6]
输出:110
解释:删除红色的边,得到 2 棵子树,和分别为 11 和 10 。它们的乘积是 110 (11*10)

示例 2:

技术图片

输入:root = [1,null,2,3,4,null,null,5,6]
输出:90
解释:移除红色的边,得到 2 棵子树,和分别是 15 和 6 。它们的乘积为 90 (15*6)

示例 3:

输入:root = [2,3,9,10,7,8,6,5,4,11,1]
输出:1025

示例 4:

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

 

提示:

  • 每棵树最多有 50000 个节点,且至少有 2 个节点。
  • 每个节点的值在 [1, 10000] 之间。
/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxProduct = function(root) {
    const all = new Set()
    function getSum(root) {
        if (!root) return 0
        const val = root.val + getSum(root.left) + getSum(root.right)
        all.add(val)
        return val
    }
    const allSum = getSum(root)
    let m = allSum;
    let max = 0;
    for(let v of all){
        let r = v*(m-v)
        if(r>max){
            max = r
        }
    }
    return max%(10**9 + 7 );
    // for (let v of all) {
    //     if (Math.abs(m - allSum / 2) > Math.abs(v - allSum / 2)) {
    //         m = v
    //     }
    // }
    // return (m * (allSum - m)) % (10 ** 9 + 7)
}
/*
let maxSum = 0;
var getSum = (r1, r2) =>{
    
}
var dfs = (root)=>{
    if(!root) return
    if(root.left) {
        let tr1 = root.left ;
        let cloneR = JSON.parse(JSON.stringify(root));
        cloneR.left = null
        let tr2 = cloneR;
        let sum = getSum(tr1, tr2)
        if(sum>maxSum){
            maxSum = sum
        }
        dfs(root.left)
    }
    if(root.right) {
         dfs(root.right)
    }
}
var maxProduct = function(root) {
    dfs(root)
};
*/

其实,一个深度优先求和在得出结果的回溯的过程中,会出现题目中需要的子树的和,然后求最大乘积即可。

我当时还想着多次套遍历树的节点,拿到每一部分的和,再求乘积。

 

数组大小减半

给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。

返回 至少 能删除数组中的一半整数的整数集合的最小大小。

 

示例 1:

输入:arr = [3,3,3,3,5,5,5,2,2,7]
输出:2
解释:选择 {3,7} 使得结果数组为 [5,5,5,2,2]、长度为 5(原数组长度的一半)。
大小为 2 的可行集合有 {3,5},{3,2},{5,2}。
选择 {2,7} 是不可行的,它的结果数组为 [3,3,3,3,5,5,5],新数组长度大于原数组的二分之一。
示例 2:

输入:arr = [7,7,7,7,7,7]
输出:1
解释:我们只能选择集合 {7},结果数组为空。
示例 3:

输入:arr = [1,9]
输出:1
示例 4:

输入:arr = [1000,1000,3,7]
输出:1
示例 5:

输入:arr = [1,2,3,4,5,6,7,8,9,10]
输出:5
 

提示:

1 <= arr.length <= 10^5
arr.length 为偶数
1 <= arr[i] <= 10^5

/**
 * @param {number[]} arr
 * @return {number}
 */
var minSetSize = function(arr) {
    let len = arr.length;
    let map = new Map();
    arr.forEach(a=>{
        if(map.has(a)){
            map.set(a, map.get(a)+1)
        }else{
            map.set(a, 1)
        }
    })
    let arr1 = [];
    for(let [key, value] of map){
        arr1.push({key, value})
    }
    // 为什么sort 减法可以排序, 如果用对象表示,Object.values 然后 sort,拿个个数的排序,其实key没必要保留。参考下面算法。
    arr1.sort((a,b)=>b.value-a.value)
    let res = 0;
    let l = len;
    let r=0;
    while(l--){
       r += map.get(arr1[res][‘key‘]);
        
       if(len / (len-r)>=2){
           
           res++;
           break;
       }
       res++;
        
    }
    return res;
};

 

/**
 * @param {number[]} arr
 * @return {number}
 */
var minSetSize = function(arr) {
	const len = arr.length
	const all = Object.values(
		arr.reduce((p, v) => {
			p[v] = (p[v] | 0) + 1
			return p
		}, {}),
	).sort((a, b) => b - a)
	let sum = 0
	for (let i = 0; i < all.length; i++) {
		if ((sum += all[i]) >= len / 2) {
			return i + 1
		}
	}
	return all.length
}

  

 为什么 sort 可以排序呢?

let arr = [4,2,3,1];
Array.prototype.sort1 = function (cb) {
	for (var i = 0; i < this.length; i++) {
		for (var j = i+1; j < this.length; j++) {
			let v1 = this[i], v2 = this[j];
			// 从小到大
                       // 只需这一步就够了,cb(a, b) 对 2值进行比较,
              // 如果是a-b>0, a-b>0,进行排序,从小到大排列;
              // 如果是 b-a >0,进行排序,从大到小,总之回调函数的函数体起到一个比较作用。
              // 之所以感觉奇怪就是,这里只有一条进行比较的语句 cb(v1, v2)>0,就可以对应 a-b 和 b-a 两种不同的排序方式 if(cb(v1, v2)>0){ let temp = this[i]; this[i] = this[j]; this[j] = temp; } //else { // 从大到小 // if(cb(v1, v2)<0){ // let temp = v1; // v1 = v2; // v2 = temp; // } //} } } return this } console.log(arr.sort1((a,b)=>b-a))

  

 V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。

V8 引擎array源码 710行开始

https://zhuanlan.zhihu.com/p/55338902

可以在github上找 v8 源码

174竞赛

标签:return   math   const   fun   quicksort   log   null   yun   tps   

原文地址:https://www.cnblogs.com/zhangzs000/p/12266194.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!