笔试挂在这道题上面了,求高效解题思路

2020-05-14 14:01:39 +08:00
 techme

如题,前两题比较简单,第三题还没有头绪就一不留神超时了 *换算几天后星期几 *x 轴上点之间最大距离 *在数组里面找出 K 个数加起来得到最大的偶数和 答题是在个类似 LeetCode 的网站上,会有跑分,优化会影响得分 这次是因为刷题少吃了亏,凌晨时候一点思路都没得

5361 次点击
所在节点    程序员
34 条回复
guyeu
2020-05-14 14:07:40 +08:00
第三个题可以转化为数组内最小的正奇数是几。。。
techme
2020-05-14 14:14:15 +08:00
@guyeu
是不是这样,如果 K 是 3,那么结果就可能是 (奇+奇+偶)(偶+偶+偶)
在我排序数组后
找到最大的两个奇数和最大的一个偶数
找到最大的三个偶数
然后比较它们和的大小
Biggoldfish
2020-05-14 14:15:57 +08:00
排个序,把前 K 个加起来得到一个和,和是偶数直接返回;和是奇数的话,把前 K 个中最小的奇数换成后面 N - K 个中最大的偶数 或者 把前 K 个中最小的偶数换成后面 N - K 个中最大的奇数,答案一定是两者中较大的一个,如果两者均为奇数,return -1 。
guyeu
2020-05-14 14:17:33 +08:00
@techme #2 去掉所有的负数,求和,如果和是奇数,就减去最小的奇数返回,如果和是偶数,就直接返回。
rabbbit
2020-05-14 14:25:39 +08:00
function isEven(num) {
...return num % 2 === 0;
}

function solution(A, K) {
...if (K === 0) {
......return -1;
...}
...let maxNum = -1;
...function dp(i, sum, remain) {
......if (remain === 0) {
.........if (isEven(sum) && sum > maxNum) {
............maxNum = sum;
.........}
.........return;
......}
......for (let j = i + 1; j < A.length; j++) {
.........dp(j, sum + A[j], remain - 1);
......}
...}
...for (let i = 0; i < A.length; i++) {
......dp(i, A[i], K - 1);
...}
...return maxNum;
}

console.log(solution([4, 9, 8, 2, 6], 3));
console.log(solution([5, 6, 3, 4, 2], 5));
console.log(solution([7, 7, 7, 7, 7], 1));
console.log(solution([10000], 2));
console.log(solution([2, 3, 3, 5, 5], 3));
Jrue0011
2020-05-14 14:28:04 +08:00
@guyeu 不用考虑负数吧,题目说都是正数
@Biggoldfish 我也是这个想法,不过和是奇数只考虑到了替换掉最小的奇数,忘了还能换偶数这回事。。。
fancy111
2020-05-14 14:34:55 +08:00
最多中级题。
先从大到小排序,找出前 K 个偶数,如果有就相加 return 结果,如果没有或者少于 K 个,就把最大的奇数加进来。
特殊情况返回-1 或者全和。
如果要其他骚操作,也可以加入数据结构。
noogler67
2020-05-14 14:51:18 +08:00
定义一种数据结构,要么存一个偶数,要么存两个奇数。然后把奇数从大到小排列转成这种数据结构。然后把所有这种数据结构根据平均数排序。
然后取前 k 个数,如果第 k 个数只能取到一个奇数,就取下一个偶数。
techme
2020-05-14 15:15:06 +08:00
techme
2020-05-14 15:28:59 +08:00
@rabbbit 这个递归解法挺好,学习了,感谢
lenqu
2020-05-14 15:42:51 +08:00
@Biggoldfish 比动态规划好
daozhihun
2020-05-14 15:52:30 +08:00
lz 是面试的 ms 嘛
cloudzhou
2020-05-14 16:47:08 +08:00
最后和是偶数,那么 偶数 = n 个偶数 + m 个奇数 ,其中个数 m 是偶数,m + n = k,k 是总个数。
要求最大值,将数组分成 偶数数组,奇数数组,从大到小排序。
如果 k 是奇数,k-1 个最大偶数,1 最大奇数,就是答案。
如果 k 是偶数,首先选取 n = k,然后记录总和;
L: 然后 n-2,剔除最后 2 个偶数,加上前 2 个奇数,在算一下总和和之前对比(如果这两奇数和小于提出的两偶数和,直接可以 break);
重复 L,知道偶数数组或者奇数数组为空,不断比较最大的和
cloudzhou
2020-05-14 16:50:25 +08:00
上面 偶数数组,奇数数组,比较就是两个起始 index i, j,一个左移,一个右移,不断逼近的结果,最后得到 i, j
nznd
2020-05-14 16:56:53 +08:00
楼上那些解法妙啊,学习到了
islxyqwe
2020-05-14 17:02:53 +08:00
按奇偶分组,然后分别排序。如果偶数的前两个和比奇数的前两个和大,从偶数提取两个;否则从奇数提取两个。(有一方个数不足 2 个时,只从另一方提取)
还需取的数不足两个时如果还需提取 1 个就从偶数提取一个,不能提就返回-1
islxyqwe
2020-05-14 17:06:21 +08:00
不对,不能处理[20,18,5,3] k=3 的情况,不太行
ncabhd
2020-05-14 17:39:29 +08:00
@Biggoldfish #3 这个解法是对的,在优化就是分奇偶两数组排序查找,从时间复杂度上来讲,差别不是很大
@techme 贴的代码有个小问题全选没有验证奇偶;还有个可以优化的地方是数组已经是有序,C#的 Any 的实现不是很清楚,我暂且认为是扫描整个数组,这个是没有必要的。
@rabbbit #5 @techme 这个应该不能算是 DP,应该是 DFS,将所有情况全部列出来,时间复杂度已经涉及到阶乘了
@cloudzhou #13 如果 K 是奇数,k-1 最大偶数和 1 最大奇数答案是奇数的。而且这个也要按照 L 去计算。
rabbbit
2020-05-14 17:44:44 +08:00
@ncabhd
嗯,写完了才发现时间复杂度太大了,如果体里的 k 比较小可能还能接受.
对于这道题来数暴力递归应该是不能接受的.
rabbbit
2020-05-14 17:45:45 +08:00
嗯,写完了才发现时间复杂度太大了,如果题里的 k 比较小可能还能接受.
对于这道题来说暴力递归应该是不能接受的.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/671593

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX