Comments (27)
function f1 (arr,count){
//数组从大到小排序
arr.sort((a,b) => b - a);
//计算平均值
let avg = arr.reduce((a,b) => a + b) / count;
//从大到小求和,取最接近平均值的一组,放入二维数组
let resArr = [];
let current = 0;
for (let i = 0; i < count-1; i++) {
if(current + arr[arr.length-1]/2 < avg && i){
arr.pop();
resArr[i-1].push(arr[arr.length-1]);
}
current = 0;
resArr[i] = [];
arr.forEach((item,index) => {
current += item;
arr.splice(index,1);
resArr[i].push(item);
if(current > avg){
current -= item;
arr.splice(index,0,item);
resArr[i].pop();
}
})
}
resArr[count-1] = arr;
return resArr
}
//测试,第一个参数为数组,第二个为份数
f1([11,42,23,4,5,6,4,5,6,11,23,42,56,78,90],3)
from fe-interview.
@Genzhen
// 在某些情况下获取的不是最优解
// 输入 [1,2,3,4,5,6,7,8]
// 结果是: [[8, 3, 2], [6, 5, 1], [7, 4]] 三个数组项的和分别为 13,12,11
// 最优解应该为 [[8, 4], [6, 5, 1], [7, 3, 2]] 三个数组项的和分别为 12,12,12
from fe-interview.
**:排序+双端遍历 即可实现
function findPart(arr) {
arr = arr.sort((a, b) => a - b);
const sum = arr.reduce((pre, cur) => pre + cur, 0);
const part = Math.floor(sum / 3);
function getPart() {
const tmp = [];
let i = 0, j = arr.length - 1;
while(i <= j) {
let flag = false;
let tmpSum = tmp.reduce((pre, cur) => pre + cur, 0);
if((tmpSum + arr[i]) <= part) {
flag = true;
tmp.push(arr[i]);
i++;
}
if((tmpSum + arr[j]) <= part) {
flag = true;
tmp.push(arr[j]);
j++;
}
if(!flag){
break;
}
}
arr = arr.slice(i, j - 1);
return tmp;
}
return [getPart(), getPart(), getPart()];
}
findPart([11,42,23,4,5,6,4,5,6,11,23,42,56,78,90]);
结果
[4, 90, 4, 5, 5, 6, 6, 11]
[11, 78, 23, 23]
[42, 56]
from fe-interview.
var a = [11, 42, 23, 4, 5, 6, 4, 5, 6, 11, 23, 42, 56, 78, 90]
var res = [{sum: 0, arr: []}, {sum: 0, arr: []}, {sum: 0, arr: []}]
// 从大到小排序,最后放细沙
a.sort((a,b) => b-a).map(el => {
var min = res.sort((a,b) => a.sum - b.sum)[0]
min.sum += el
min.arr.push(el)
})
res.map(el => el.arr)
from fe-interview.
// 思路:把大的数插入数组,再用小的数找齐三组数和的差距,就可以尽量均匀的分成三组了。
// 代码逻辑:数组从大到小排序,把数依次往和最小的数组中插入。
function sliceArray(arr) {
const newErr = [...arr].sort((a, b) => b - a); // 一定要倒序排列,大的排在前面。
const arr1 = [], arr2 = [], arr3 = []; // 用于储存结果的三个数组
let arr1Sum = 0, arr2Sum = 0, arr3Sum = 0; // 三个数组对应数的和
for (const item of newErr) {
const min = Math.min(arr1Sum, arr2Sum, arr3Sum);
switch (min) {
case arr1Sum:
arr1.push(item);
arr1Sum += item;
break;
case arr2Sum:
arr2.push(item);
arr2Sum += item;
break;
case arr3Sum:
arr3.push(item);
arr3Sum += item;
break;
default:
break;
}
}
return [arr1, arr2, arr3];
}
from fe-interview.
function foo(arr) {
let AMOUNT = arr.length
if (!AMOUNT) return false;
if (AMOUNT === 3) return arr;
arr.sort((a, b) => a - b);
let total = 0;
let maxNumberTotal = 0;
for (let i = 0; i < AMOUNT; i++) {
total += arr[i];
}
maxNumberTotal = total / 3;
let tempTotal = arr[AMOUNT - 1];
let firstArr = [arr[AMOUNT - 1]];
let delIndex = [AMOUNT - 1];
let firstIndex = -1;
// 获取第一份数组
for (let i = AMOUNT - 2; i > 0; i--) {
const el = arr[i];
tempTotal += el; // 每次拿最大的;
firstArr.push(el);
delIndex.push(i);
if (tempTotal === maxNumberTotal) { // 刚好等于最大值跳出循环
break;
} else if (tempTotal > maxNumberTotal) { // 发现超过最大值, 减回去
tempTotal -= el;
delIndex.pop();
firstArr.pop();
} else if (tempTotal < maxNumberTotal) { // 发现超过最小值, 处理边界问题
let nextTotal = tempTotal + arr[i + 1]
if (maxNumberTotal - tempTotal < Math.abs(maxNumberTotal - nextTotal)) { // 当前总值比上一个总值大; 这里是临界值, 说明上一个总值肯定是一个比最大值大, 所以这里需要和绝对值比较
if (maxNumberTotal - tempTotal > arr[0]) { // 如果下一个平局值和总值相减, 比数组第一个数还大, 说明还可以继续走下去;
continue;
} else {
break;
}
}
}
}
for (let i = 0; i < delIndex.length; i++) {
arr.splice(delIndex[i], 1)
}
AMOUNT = arr.length; // 注意每次的arr都是不一样的
let secondArr = [arr[AMOUNT - 1]];
delIndex = [AMOUNT - 1];
let secondIndex = -1;
tempTotal = arr[AMOUNT - 1];
// 获取第二份数组
for (let i = AMOUNT - 2; i > 0; i--) {
const el = arr[i];
tempTotal += el; // 每次拿最大的;
secondArr.push(el);
delIndex.push(i);
if (tempTotal === maxNumberTotal) { // 刚好等于最大值跳出循环
break;
} else if (tempTotal > maxNumberTotal) { // 发现超过最大值, 减回去
tempTotal -= el;
delIndex.pop();
secondArr.pop();
} else if (tempTotal < maxNumberTotal) { // 发现超过最小值, 处理边界问题
let nextTotal = tempTotal + arr[i + 1]
if (maxNumberTotal - tempTotal < Math.abs(maxNumberTotal - nextTotal)) { // 当前总值恒小于下一个总值; 这里是临界值
if (maxNumberTotal - tempTotal > arr[0]) {
continue;
} else {
break;
}
}
}
}
for (let i = 0; i < delIndex.length; i++) {
arr.splice(delIndex[i], 1)
}
// 公平处理, 当出现极差情况就需要做公平处理了, 这里暂时不考虑极差情况
return [firstArr, secondArr, arr]
}
from fe-interview.
没这么麻烦吧 其实直接就是瀑布流布局的**啊
function makeAlmostEqual (arr, part) {
let orderedArr = arr.sort((a,b) => b - a)
let res = Array(part).fill(void(0)).map(() => [])
orderedArr.forEach(value => {
let minArrIndex = getMinArrIndex(res)
res[minArrIndex].push(value)
})
return res
}
function getSum (arr) {
return arr.reduce((sum, v) => sum + v, 0)
}
function getMinArrIndex (arrs) {
let minArrIndex = 0
arrs.forEach((arr, index) => {
if (getSum(arrs[minArrIndex]) > getSum(arrs[index])) {
minArrIndex = index
}
})
// console.log(arrs)
return minArrIndex
}
makeAlmostEqual([1, 65, 4, 32, 95, 33, 9, 3], 3)
只要注意数组要倒序排列就好了
from fe-interview.
leetcode 有类似的题吗?
from fe-interview.
leetcode 有类似的题吗?
@AielloChan 在leetcode 可以练习自己的解题思路,培养解题思维,练的多了,看到这样的题,就会知道怎么去解了,在leetcode 也不要盲目的从头开始刷,最好是分类练习
from fe-interview.
@zxmajunhong 算法题不是用来实际用的,是来练你的逻辑思维和语法熟练度的,理论和实际是两码事,理论好了实操才会更好,没有理论支持,实操能好到哪儿去?最多也是搬砖工
from fe-interview.
// 若总和不能被 3 整除,说明不能分成相等的 3 个部分,然后return了,题目不是说尽量相等嘛???
from fe-interview.
// 若总和不能被 3 整除,说明不能分成相等的 3 个部分,然后return了,题目不是说尽量相等嘛???
答题已更新哈
from fe-interview.
题目来自于背包问题变种,思路比较简单,动态规划解决。
from fe-interview.
const numSort = (arr) => {
return arr.sort((a, b) => b - a)
};
const numArr = numSort([11, 42, 23, 4, 5, 6, 4, 5, 6, 11, 23, 42, 56, 78, 90]);
const sumTotal = eval(numArr.join('+'));
let a = 0, b = 0, c = 0;
const sumFN = (x) => {
let newX = x;
numArr.map((num, index) => {
if ((newX + num) <= Math.ceil(sumTotal / 3)) {
newX = newX + num;
numArr.splice(index, 1);
} else {
return false;
}
})
return newX
};
a = sumFN(a);
b = sumFN(b);
c = eval(numArr.join('+'));
console.log(a, b, c);
136 136 134
from fe-interview.
// 若总和不能被 3 整除,说明不能分成相等的 3 个部分,然后return了,题目不是说尽量相等嘛???
感谢指出问题,答案已更新哈
from fe-interview.
@Genzhen
// 在某些情况下获取的不是最优解
// 输入 [1,2,3,4,5,6,7,8]
// 结果是: [[8, 3, 2], [6, 5, 1], [7, 4]] 三个数组项的和分别为 13,12,11
// 最优解应该为 [[8, 4], [6, 5, 1], [7, 3, 2]] 三个数组项的和分别为 12,12,12
感谢指出问题,答案已更新哈
from fe-interview.
function sliceArray (arr, count) {
// 平均值向上取整
let average = Math.ceil(arr.reduce((acc, v) => acc + v, 0) / count)
// 由大到小排列
arr.sort((n1, n2) => n2 - n1)
const getArr = () => {
let sum = 0, newArr = [] // 存相应数据
arr.map((v, i) => {
if (sum + v <= average) {
sum += v
newArr.push(v)
arr.splice(i, 1)
}
})
return newArr;
}
let backArr = new Array(count).fill(0)
backArr.forEach((x, i) => {
backArr[i] = i === backArr.length - 1 ? arr : getArr()
})
return backArr
}
from fe-interview.
输入 [1,1,12,12]
结果是: [[1], [1], [12,12]] 三个数组项的和分别为 1,1,24
最优解应该为 [[1, 1], [12], [12]] 三个数组项的和分别为 2,12,12
from fe-interview.
输入 [1,1,12,12]
结果是: [[1], [1], [12,12]] 三个数组项的和分别为 1,1,24
最优解应该为 [[1, 1], [12], [12]] 三个数组项的和分别为 2,12,12
@FlyingRabbit7 感谢指出问题Thanks♪(・ω・)ノ 答案已更新哈
from fe-interview.
let arr = [11,42,23,4,5,6,4,5,6,11,23,42,56,78,90]
arr.sort((a,b)=>a-b)
let arr0 = []
let arr1 = []
let arr2 = []
let getsum = function(arr){
return arr.reduce((a,b)=>{
return a+b
},0)
}
let sum = getsum(arr)
let avg = sum/3
console.log(avg)
// 先分大数,大数影响分布均衡
while(arr.length>0){
// console.log(arr.length)
let sum0 = getsum(arr0)
let sum1 = getsum(arr1)
let sum2 = getsum(arr2)
if(Math.min(sum0,sum1,sum2)===sum0 && sum0<=avg){
let popnum = arr.pop()
arr0.push(popnum||0)
}
if(Math.min(sum0,sum1,sum2)===sum1 && sum1<=avg){
let popnum = arr.pop()
arr1.push(popnum||0)
}
if(Math.min(sum0,sum1,sum2)===sum2 && sum2<=avg){
let popnum = arr.pop()
arr2.push(popnum||0)
}
}
console.log(arr0,arr1,arr2,getsum(arr0),getsum(arr1),getsum(arr2)) //
[90, 23, 11, 6, 5] [78, 42, 11, 4] [56, 42, 23, 6, 5, 4] 135 135 136
from fe-interview.
function f1(arr, count) {
arr.sort((a, b) => a - b);
let max = 0;
const sums = Array(count).fill(0);
const arrs = Array(count).fill(0).map(() => []);
while (arr.length > 0) {
for (let i = 0; i < count && arr.length > 0; i++) {
if (sums[i] <= max) {
const item = arr.pop();
sums[i] += item;
arrs[i].push(item);
} else {
max = sums[i];
}
}
}
console.log(arrs, sums);
return arrs;
}
//测试,第一个参数为数组,第二个为份数
f1([1, 2, 3, 4, 5, 6, 7, 8], 3)
from fe-interview.
能说说这个的实际应用场景吗
from fe-interview.
没这么麻烦吧 其实直接就是瀑布流布局的**啊
function makeAlmostEqual (arr, part) {
let orderedArr = arr.sort((a,b) => b - a)
let res = Array(part).fill(void(0)).map(() => [])
orderedArr.forEach(value => {
let minArrIndex = getMinArrIndex(res)
res[minArrIndex].push(value)
})
return res
}function getSum (arr) {
return arr.reduce((sum, v) => sum + v, 0)
}function getMinArrIndex (arrs) {
let minArrIndex = 0
arrs.forEach((arr, index) => {
if (getSum(arrs[minArrIndex]) > getSum(arrs[index])) {
minArrIndex = index
}
})
// console.log(arrs)
return minArrIndex
}makeAlmostEqual([1, 65, 4, 32, 95, 33, 9, 3], 3)
只要注意数组要倒序排列就好了
@Aeolos1994
// 在某些情况下获取的不是最优解
// 输入 [1,2,3,4,5,6,7,8]
// 结果是: [[8, 3, 2], [7, 4, 1], [6, 5]] 三个数组项的和分别为 13,12,11
// 最优解应该为 [[8, 4], [6, 5, 1], [7, 3, 2]] 三个数组项的和分别为 12,12,12
from fe-interview.
function f1 (arr,count){ //数组从大到小排序 arr.sort((a,b) => b - a); //计算平均值 let avg = arr.reduce((a,b) => a + b) / count; //从大到小求和,取最接近平均值的一组,放入二维数组 let resArr = []; let current = 0; for (let i = 0; i < count-1; i++) { if(current + arr[arr.length-1]/2 < avg && i){ arr.pop(); resArr[i-1].push(arr[arr.length-1]); } current = 0; resArr[i] = []; arr.forEach((item,index) => { current += item; arr.splice(index,1); resArr[i].push(item); if(current > avg){ current -= item; arr.splice(index,0,item); resArr[i].pop(); } }) } resArr[count-1] = arr; return resArr } //测试,第一个参数为数组,第二个为份数 f1([11,42,23,4,5,6,4,5,6,11,23,42,56,78,90],3)
你这有个bug,就是current > avg的时候,arr再splice回去后,arr forEach的index会受影响。
let arr = [11, 42, 23, 4, 5, 6, 4, 5, 6]
我试这个的时候发现的。不过好棒,我也想到这么做了,但是没写出来!学习了~
from fe-interview.
// 借助上面大佬们的**写出来的改版
let arr = [11, 42, 23, 4, 5, 6, 4, 5, 6, 11, 23, 42, 56, 78, 90]
function f1(arr, count) {
// 从大到小排序
arr.sort((a, b) => b - a)
// 求和 & 平均数
const avg = Math.ceil(arr.reduce((acc, cur) => acc + cur) / count)
// for循环相加
const resAry = []
for (let i = 0; i < count - 1; i++) {
let total = 0
resAry[i] = []
arr.forEach((item, index) => {
if (avg >= total + item) {
total += item
resAry[i].push(item)
arr.splice(index, 1)
}
})
}
resAry[count - 1] = arr
return resAry
}
`
from fe-interview.
@SnailOwO ,输入[1,2,3,4]不是最优解
from fe-interview.
var a = [11, 42, 23, 4, 5, 6, 4, 5, 6, 11, 23, 42, 56, 78, 90] var res = [{sum: 0, arr: []}, {sum: 0, arr: []}, {sum: 0, arr: []}] // 从大到小排序,最后放细沙 a.sort((a,b) => b-a).map(el => { var min = res.sort((a,b) => a.sum - b.sum)[0] min.sum += el min.arr.push(el) }) res.map(el => el.arr)
思路跟你一样,但你的代码超简洁
from fe-interview.
Related Issues (20)
- Day378:说一下什么是 Http 协议无状态?怎么解决 Http 协议无状态?
- Day379:如果让你来实现一个前端监控系统,应该考虑什么?如何去实现?
- Day380:实现一个系统,统计前端页面性能、页面 JS 报错、用户操作行为、PV/UV、用户设备等消息,并进行必要的监控报警。方案如何设计,用什么技术点,什么样的系统架构,难点会在哪里? HOT 3
- Day381:说一下 JavaScript 严格模式下有哪些不同?
- Day382:说一下 setTimeout 和 setInterval 的区别,包含内存方面的分析?
- Day383:说下 React 的 useEffect、useCallback、useMemo HOT 2
- Day384:JavaScript 中如何实现一个类?怎么实例化这个类? HOT 2
- Day385:在一个 DOM 上同时绑定两个点击事件:一个用捕获,一个用冒泡。事件会执行几次?先执行冒泡还是捕获? HOT 9
- Day386:写一个通用的事件侦听器函数 HOT 3
- 定时函数 HOT 1
- 小程序不维护了吗? HOT 10
- --
- 小程序里面的内容还有其他地方能学习吗
- 求小程序哇!!不然学习效率太低了 HOT 1
- 现在还能在哪里看题目答案吗?小程序关闭了😭😭 HOT 1
- #### 1)为什么会有Event Loop
- > > > @Genzhen 请教一下大佬,如果在render里面结构赋值也会影响性能吗?比如 const { page, size } = this.state这种的? HOT 1
- 考察原型链
- issue路径错误,提不了pr,可见下图
- vue中&nextTick的原理
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fe-interview.