174竞赛
Posted zhangzs000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了174竞赛相关的知识,希望对你有一定的参考价值。
分裂二叉树的最大乘积
给你一棵二叉树,它的根为 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竞赛的主要内容,如果未能解决你的问题,请参考以下文章
借助全新 MATLAB® 适配器代码示例读取英特尔® 实感? 摄像头数据流